Errori semantici Java | Perché il programmatore Java deve riconoscere gli errori semantici

Mar 08 2023
Unisciti a JAVA FLAMES Molte persone trovano difficile capire la differenza tra errori semantici ed errori sintattici (sintassi) nel codice Java, ma sono diversi. Puoi vedere un errore semantico quando la sintassi del tuo codice è corretta ma l'utilizzo del codice non è corretto.

Unisciti a JAVA FLAMES

Molte persone trovano difficile capire la differenza tra errori semantici ed errori sintattici (sintassi) nel codice Java, ma sono diversi. Puoi vedere un errore semantico quando la sintassi del tuo codice è corretta ma l'utilizzo del codice non è corretto.

· Cos'è un errore semantico?
· Come vengono rilevati gli errori semantici?
· Errori semantici comuni

Cos'è un errore semantico?

Un errore semantico è un problema nel codice che impedisce all'interprete di comprenderlo. Potrebbe non esserci nulla di sbagliato nella logica che hai scritto, ma causerà il crash del programma nel modo in cui hai scritto. Ad esempio, il codice seguente produrrà un risultato errato in un errore di runtime semantico:

var a = 1 // No error
var b = 2 // No error
var c = 3 // No error
a + c = b

Gli errori semantici vengono rilevati in fase di compilazione e puoi pensarli come errori di analisi statica. Ad esempio , se si tenta di eseguire una variabile che non è stata dichiarata, verrà generato un errore semantico: un errore semantico si verifica quando un programmatore scrive codice che non riesce a comunicare lo scopo previsto. Questo è diverso da un errore di sintassi, che si verifica quando il codice è sintatticamente corretto ma non esegue l'attività progettata.

In altre parole, un errore semantico si riferisce a un programma errato che produce un risultato che non ha senso. Ad esempio , se un'app meteo dicesse "Caldo e soleggiato" anche quando fuori pioveva, si tratterebbe di un errore semantico. Il programma non ha prodotto ciò che avrebbe dovuto produrre.

Come vengono rilevati gli errori semantici?

alcuni degli errori semantici (gli errori semantici statici) vengono rilevati dal compilatore, che genera un messaggio che indica il tipo di errore e la posizione nel file sorgente Java in cui si è verificato l'errore (si noti che l'errore effettivo potrebbe essersi verificato prima della posizione segnalato dal compilatore).

A questo punto, abbiamo descritto gli errori semantici statici . In ogni caso, il compilatore contrassegna un errore semantico statico quando un requisito del linguaggio di programmazione non è soddisfatto (tipi non validi).

C'è un altro tipo di problema: cosa succede se il tuo programma viene compilato ed eseguito, ma non fa quello che volevi che facesse? Il computer sta facendo esattamente quello che hai programmato, ma quello che hai programmato era sbagliato. Questo è un altro tipo di errore semantico: quando il programmatore utilizza in modo errato il linguaggio di programmazione per risolvere il problema.

A differenza di un errore semantico statico, un errore semantico dinamico ha a che fare con il significato. Se un programma contiene questo tipo di errore, verrà eseguito correttamente, ma non restituirà il risultato corretto.

Il debug non è così facile con un errore semantico. Vediamo un esempio.

/**
 * This program prints the total benefit for the company
 * 
*/
public class TotalBenefit {
 public static void main(String[] args) {
  int branch1 = 250; 
        int branch2 = 500;
        System.out.println("The total benefit is  $" + (branch1 * branch2));
 }
}

Errori semantici comuni

Errore di tipo incompatibile

Questo errore di sintassi è molto comune nei principianti. Nei linguaggi di programmazione compilati come Java, puoi solo assegnare valori a variabili compatibili.

Compatibile significa che hanno lo stesso tipo o hanno tipi che possono essere convertiti automaticamente dal compilatore.

Nell'esempio seguente puoi vedere che in Java non puoi assegnare un double a una variabile intera. Alcuni linguaggi di programmazione potrebbero eseguire la conversione automaticamente, ma se visualizzi l'errore riportato di seguito, la correzione è semplice. Basta cambiare il tipo della variabile 'a', oppure assegnare un valore intero invece che doppio (5.5).

Questo tipo di errore semantico può essere complicato perché il compilatore segnalerà alcuni errori e non altri. Ad esempio, se si tenta di assegnare un float a una variabile int, il compilatore visualizza un messaggio di errore.

D'altra parte, se si assegna un int a una variabile float, il compilatore esegue una conversione automatica del tipo in int per renderlo float. Il problema con questo secondo scenario è che può introdurre silenziosamente errori nel tuo codice, specialmente se intendevi davvero usare un float.

"la variabile <X> potrebbe non essere stata inizializzata"

Ciò si verifica quando una variabile locale dichiarata all'interno di un metodo non è stata inizializzata. Può verificarsi quando una variabile senza un valore iniziale fa parte di un'istruzione if.

int x;
if (condition) {
  x = 5;
}
System.out.println(x); // x may not have been initialized

È possibile convertire tra molti tipi diversi in Java. Tuttavia, non importa quanto desideri convertire un valore booleano in un int, Java non te lo permetterà. Il concetto di eseguire il cast è sintatticamente corretto, ma lo stai applicando in modo errato, rendendolo un errore semantico che il compilatore rileva sempre.

L'errore "tipi inconvertibili" si verifica quando il codice Java tenta di eseguire una conversione illegale.

TypeInvocationConversionTest.java:12: inconvertible types
found   : java.util.ArrayList<java.lang.Class<? extends TypeInvocationConversionTest.Interface1>>
required: java.util.ArrayList<java.lang.Class<?>>
lessRestrictiveClassList = (ArrayList<Class<?>>) classList;
                                                 ^

“variabile non statica . . . non può essere referenziato da un contesto statico”

Questo errore si verifica quando il compilatore tenta di accedere a variabili non statiche da un metodo statico

public class StaticTest {
private int count=0;
   public static void main(String args[]) throws IOException {
       count++; //compiler error: non-static variable count cannot be referenced from a static context
   }
}

  • Dichiara la variabile come statica nella firma.
  • Controlla il codice in quanto può creare un'istanza di un oggetto non statico nel metodo statico.

Questo problema si verifica quando il codice Java tenta di chiamare un metodo non statico in una classe non statica. Ecco un esempio:

class Sample {
  private int age;
  public void setAge(int a) {
    age=a;
  }
  public int getAge() {
    return age;
  }
  public static void main(String args[]) {
    System.out.println(“Age is:”+ getAge());
   }
  }

Exception in thread “main” java.lang.Error: Unresolved compilation problem:
Cannot make a static reference to the non–static method getAge() from the type Sample

Riceverai il messaggio "(array) <X> non inizializzato" quando un array è stato dichiarato ma non inizializzato. Gli array hanno una lunghezza fissa, quindi ogni array deve essere inizializzato con la lunghezza desiderata.

Il seguente codice è accettabile:

AClass[] array = {object1, object2}
  As is:
       AClass[] array = new AClass[2];
       …
       array[0] = object1;
       array[1] = object2;
  But not:
       AClass[] array;
       …
       array = {object1, object2};

Questo problema si verifica quando gli operatori vengono usati per i tipi, non nella loro definizione.

Gli operatori sono definiti solo per determinati tipi, sebbene la conversione di tipo implicita sia consentita tra determinati tipi numerici:

int a = 5; 
boolean b = true;
int c = a + b; // Error, can't add a boolean value double 
d = a + 1.4;  // OK, int is implicitly converted to double

Ciò accade spesso quando il codice Java tenta di utilizzare una stringa di tipo in un calcolo. Per risolverlo, la stringa deve essere convertita in un numero intero o float.

Possibile perdita di precisione

A volte puoi applicare il casting in modo errato. Ad esempio, il cast di un float su un int funziona correttamente, ma perdendo la parte decimale del numero.

La "possibile perdita di precisione" si verifica quando a una variabile vengono assegnate più informazioni di quante ne possa contenere. Se ciò accade, i pezzi verranno gettati via. Se questo va bene, allora il codice deve dichiarare esplicitamente la variabile come un nuovo tipo.

Questo errore si verifica quando si tenta di assegnare un valore di precisione maggiore a una variabile di precisione inferiore senza un cast di tipo esplicito. Sorprendentemente, forse, i valori letterali in virgola mobile sono di tipo doublee riceverai questo messaggio se provi ad assegnarne uno a una variabile di tipo float:

float sum = 0.0;  // Error, literal is not of type float

float sum = 0.0f;   // OK float sum = (float) 0.0;  // OK

Questa perdita di precisione può influire sull'output dell'applicazione in modi imprevisti e fare in modo che l'output rifletta un valore diverso da quello previsto. Il compilatore non trova mai questo tipo di errore perché hai applicato specificamente un cast alla variabile e il compilatore si aspetta che tu sappia cosa stai facendo.

Applicazione scorretta dell'ambito

Qualsiasi variabile dichiarata all'interno di un metodo ha lo stesso ambito (visibilità ad altre parti dell'applicazione, in altre parole) del metodo. Di conseguenza, non è possibile dichiarare una variabile int statica privata all'interno di un metodo. Invece, devi definire la variabile globalmente in questo modo:

public class PrivateVar
{
   // This declaration works.
   private static int PrivateInt = 3;
   public static void main(String[] args)
   {
      // This declaration doesn’t work.
      private static int PrivateInt = 3;
   }
}

Ecco alcuni altri casi generali di errori semantici in Java

Mancate corrispondenze di tipo : esistono molti modi per utilizzare il tipo errato in C#. L'esempio sopra è un modo. Ecco alcuni altri modi possibili:

  • Passaggio del tipo errato di valore a un metodo.
  • Restituzione del tipo errato di valore da un metodo.
  • Impostazione del tipo errato di valore su una proprietà.
  • Impostazione del tipo errato di valore su un campo.
  • Impostazione del tipo errato di valore su una variabile locale.
  • Utilizzo di un tipo in un elenco di argomenti generici che non è conforme ai vincoli di tipo generico.
  • Passaggio del numero errato di argomenti a una chiamata al metodo.
  • Passaggio del numero errato di indici a un array o a un indicizzatore.
  • Utilizzo del numero errato di argomenti di tipo generico per un tipo o metodo generico.
  • Utilizzo di nomi non definiti: utilizzo di uno spazio dei nomi, un tipo, un metodo, un campo, una variabile o un nome di proprietà che non esiste.
  • Definizione di due tipi nello stesso spazio dei nomi con lo stesso nome
  • Definizione di due metodi nella stessa classe con lo stesso elenco di argomenti e lo stesso nome.
  • Definizione di una proprietà, campo o tipo annidato che ha lo stesso nome di un'altra proprietà, campo o tipo annidato nello stesso tipo proprietario.
  • Definizione di due variabili locali negli ambiti uguali o discendenti con gli stessi nomi.

Sostieni la nostra pubblicazione seguendola

Spring 3.0 e le sue funzionalità Domanda di intervista basata sul flusso Java8 più frequente - Parte finale Semaforo | Java Concurrent API In che modo ChatGPT trasformerà la SEO: vantaggi e sfide Quali sono le cause degli errori di sintassi e come evitarli| Come il compilatore Java rileva gli errori di sintassi … La guida completa alla creazione di una piattaforma ICO white-label da estraneo mi ha aiutato a comprendere la triste verità della comunicazione moderna Medio? Non ho visto di essere uno dei migliori scrittori su Medium RestTemplate | Cliente finto | WebClient con avvio a molla Come creare un semplice progetto Quarkus con la codifica di integrazione del database: appiattisci un array in Javascript Automatizza il social media marketing con ChatGPT 10 widget che ogni sviluppatore Flutter deve padroneggiare Rivoluziona il tuo studio con il richiamo attivo: il metodo collaudato per conservare le informazioni per il ...