Java-Semantikfehler | Warum Java-Programmierer semantische Fehler erkennen müssen

Mar 08 2023
Treten Sie JAVA FLAMES bei. Für viele Menschen ist der Unterschied zwischen semantischen Fehlern und syntaktischen (Syntax-)Fehlern im Java-Code schwer zu verstehen, aber sie sind unterschiedlich. Sie können einen semantischen Fehler sehen, wenn die Syntax Ihres Codes korrekt ist, die Codeverwendung jedoch nicht korrekt ist.

Treten Sie JAVA FLAMES bei

Für viele Menschen ist der Unterschied zwischen semantischen Fehlern und syntaktischen (Syntax-)Fehlern im Java-Code schwer zu verstehen, aber sie sind unterschiedlich. Sie können einen semantischen Fehler sehen, wenn die Syntax Ihres Codes korrekt ist, die Codeverwendung jedoch nicht korrekt ist.

· Was ist ein semantischer Fehler?
· Wie werden semantische Fehler erkannt?
· Häufige semantische Fehler

Was ist ein semantischer Fehler?

Ein semantischer Fehler ist ein Problem in Ihrem Code, das den Interpreter daran hindert, ihn zu verstehen. An der von Ihnen geschriebenen Logik ist vielleicht nichts falsch, aber so, wie Sie es geschrieben haben, führt sie zum Absturz des Programms. Beispielsweise führt der folgende Code zu einem falschen Ergebnis in einem semantischen Laufzeitfehler:

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

Semantische Fehler werden zur Kompilierzeit erkannt und können als statische Analysefehler betrachtet werden. Wenn Sie beispielsweise versuchen, eine Variable auszuführen, die Sie nicht deklariert haben, wird ein semantischer Fehler ausgegeben: Ein semantischer Fehler tritt auf, wenn ein Programmierer Code schreibt, der seinen beabsichtigten Zweck nicht kommuniziert. Dies unterscheidet sich von einem Syntaxfehler, der auftritt, wenn der Code syntaktisch korrekt ist, aber die vorgesehene Aufgabe nicht ausführt.

Mit anderen Worten: Ein semantischer Fehler bezieht sich auf ein falsches Programm, das ein Ergebnis erzeugt, das keinen Sinn ergibt. Wenn beispielsweise eine Wetter-App „Warm und sonnig“ sagt, obwohl es draußen regnet, wäre das ein semantischer Fehler. Das Programm hat nicht das produziert, was es produzieren sollte.

Wie werden semantische Fehler erkannt?

Einige der semantischen Fehler (die statischen semantischen Fehler) werden vom Compiler erkannt, der eine Meldung generiert, die den Fehlertyp und die Position in der Java-Quelldatei angibt, an der der Fehler aufgetreten ist (beachten Sie, dass der eigentliche Fehler vor der Position aufgetreten sein könnte). vom Compiler signalisiert).

An dieser Stelle haben wir statische semantische Fehler beschrieben . In jedem Fall meldet der Compiler einen statischen semantischen Fehler, wenn eine Anforderung der Programmiersprache nicht erfüllt ist (ungültige Typen).

Es gibt noch eine andere Art von Problem: Was passiert, wenn Ihr Programm kompiliert und ausgeführt wird, aber nicht das tut, was Sie wollten? Der Computer macht genau das, was Sie programmiert haben, aber was Sie programmiert haben, war falsch. Dies ist eine andere Art von semantischem Fehler: wenn der Programmierer die Programmiersprache falsch verwendet, um das Problem zu lösen.

Im Gegensatz zu einem statischen semantischen Fehler hat ein dynamischer semantischer Fehler mit der Bedeutung zu tun. Wenn ein Programm einen solchen Fehler enthält, wird es erfolgreich ausgeführt, gibt jedoch nicht das richtige Ergebnis aus.

Bei einem semantischen Fehler ist das Debuggen nicht so einfach. Sehen wir uns ein Beispiel an.

/**
 * 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));
 }
}

Häufige semantische Fehler

Fehler bei inkompatiblen Typen

Dieser Syntaxfehler kommt bei Anfängern sehr häufig vor. In kompilierten Programmiersprachen wie Java können Sie nur kompatiblen Variablen Werte zuweisen.

Kompatibel bedeutet, dass sie denselben Typ haben oder dass sie Typen haben, die vom Compiler automatisch konvertiert werden können.

Im folgenden Beispiel sehen Sie, dass Sie in Java einer Ganzzahlvariablen kein Double zuweisen können. Einige Programmiersprachen führen die Konvertierung möglicherweise automatisch durch. Wenn Sie jedoch den folgenden Fehler sehen, ist die Lösung einfach. Ändern Sie einfach den Typ der Variablen „a“ oder weisen Sie einen ganzzahligen Wert anstelle einer doppelten Eins zu (5.5).

Diese Art von semantischem Fehler kann schwierig sein, da der Compiler einige Fehler markiert und andere nicht. Wenn Sie beispielsweise versuchen, einer int-Variablen einen Float zuzuweisen, zeigt der Compiler eine Fehlermeldung an.

Wenn Sie andererseits einer Float-Variablen ein int zuweisen, führt der Compiler eine automatische Typkonvertierung in das int durch, um es in ein float umzuwandeln. Das Problem bei diesem zweiten Szenario besteht darin, dass es stillschweigend zu Fehlern in Ihrem Code führen kann, insbesondere wenn Sie tatsächlich einen Float verwenden wollten.

„Variable <X> wurde möglicherweise nicht initialisiert“

Dies tritt auf, wenn eine in einer Methode deklarierte lokale Variable nicht initialisiert wurde. Dies kann auftreten, wenn eine Variable ohne Anfangswert Teil einer if-Anweisung ist.

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

Es ist möglich, in Java zwischen vielen verschiedenen Typen zu konvertieren. Doch ganz gleich, wie sehr Sie einen booleschen Wert in einen int-Wert umwandeln möchten, Java lässt dies nicht zu. Das Konzept zur Durchführung der Umwandlung ist syntaktisch korrekt, aber Sie wenden es falsch an, was zu einem semantischen Fehler führt, den der Compiler immer erkennt.

Der Fehler „Inkonvertierbare Typen“ tritt auf, wenn der Java-Code versucht, eine illegale Konvertierung durchzuführen.

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;
                                                 ^

„nichtstatische Variable. . . kann nicht aus einem statischen Kontext referenziert werden“

Dieser Fehler tritt auf, wenn der Compiler versucht, über eine statische Methode auf nicht statische Variablen zuzugreifen

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
   }
}

  • Deklarieren Sie die Variable in der Signatur als statisch.
  • Überprüfen Sie den Code, da er in der statischen Methode eine Instanz eines nicht statischen Objekts erstellen kann.

Dieses Problem tritt auf, wenn der Java-Code versucht, eine nicht statische Methode in einer nicht statischen Klasse aufzurufen. Hier ist ein Beispiel:

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

Sie erhalten die Meldung „(array) <X> not initialized“, wenn ein Array deklariert, aber nicht initialisiert wurde. Arrays haben eine feste Länge, daher muss jedes Array mit der gewünschten Länge initialisiert werden.

Der folgende Code ist akzeptabel:

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

Dieses Problem tritt auf, wenn Operatoren für Typen verwendet werden, nicht in deren Definition.

Operatoren werden nur für bestimmte Typen definiert, obwohl eine implizite Typkonvertierung zwischen bestimmten numerischen Typen zulässig ist:

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

Dies geschieht häufig, wenn der Java-Code versucht, eine Typzeichenfolge in einer Berechnung zu verwenden. Um das Problem zu beheben, muss die Zeichenfolge in eine Ganzzahl oder eine Gleitkommazahl konvertiert werden.

Möglicher Präzisionsverlust

Manchmal kann es vorkommen, dass der Guss falsch angewendet wird. Beispielsweise funktioniert das Umwandeln einer Gleitkommazahl in einen int-Wert einwandfrei, allerdings geht dabei der Dezimalteil der Zahl verloren.

Ein „möglicher Präzisionsverlust“ tritt auf, wenn einer Variablen mehr Informationen zugewiesen werden, als sie aufnehmen kann. In diesem Fall werden Teile weggeworfen. Wenn dies in Ordnung ist, muss der Code die Variable explizit als neuen Typ deklarieren.

Dieser Fehler tritt auf, wenn versucht wird, einer Variablen mit niedrigerer Genauigkeit einen Wert mit höherer Genauigkeit ohne explizite Typumwandlung zuzuweisen. Überraschenderweise sind Gleitkommaliterale vielleicht vom Typ doubleund Sie erhalten diese Meldung, wenn Sie versuchen, eines einer Variablen vom Typ zuzuweisen float:

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

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

Dieser Präzisionsverlust kann sich auf unerwartete Weise auf die Ausgabe Ihrer Anwendung auswirken und dazu führen, dass die Ausgabe einen anderen Wert als den erwarteten wiedergibt. Der Compiler findet diese Art von Fehler nie, da Sie speziell eine Umwandlung auf die Variable angewendet haben und der Compiler erwartet, dass Sie wissen, was Sie tun.

Scoping falsch anwenden

Jede Variable, die Sie innerhalb einer Methode deklarieren, hat denselben Gültigkeitsbereich – mit anderen Worten: Sichtbarkeit für andere Teile der Anwendung – wie die Methode. Folglich können Sie innerhalb einer Methode keine private statische int-Variable deklarieren. Stattdessen müssen Sie die Variable global wie folgt definieren:

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;
   }
}

Hier sind einige andere allgemeine Fälle von semantischen Fehlern in Java

Typkonflikte – Es gibt viele Möglichkeiten, in C# den falschen Typ zu verwenden. Das obige Beispiel ist eine Möglichkeit. Hier sind einige andere mögliche Wege:

  • Übergabe des falschen Werttyps an eine Methode.
  • Gibt von einer Methode den falschen Werttyp zurück.
  • Festlegen des falschen Werttyps für eine Eigenschaft.
  • Den falschen Werttyp für ein Feld festlegen.
  • Den falschen Werttyp für eine lokale Variable festlegen.
  • Verwendung eines Typs in einer generischen Argumentliste, der nicht den Einschränkungen des generischen Typs entspricht.
  • Übergabe der falschen Anzahl von Argumenten an einen Methodenaufruf.
  • Übergabe der falschen Anzahl von Indizes an ein Array oder einen Indexer.
  • Verwendung der falschen Anzahl generischer Typargumente für einen generischen Typ oder eine generische Methode.
  • Verwendung undefinierter Namen – Verwendung eines Namensraums, Typs, einer Methode, eines Felds, einer Variablen oder eines Eigenschaftsnamens, der nicht existiert.
  • Definieren von zwei Typen im selben Namespace mit demselben Namen
  • Definieren von zwei Methoden in derselben Klasse mit derselben Argumentliste und demselben Namen.
  • Definieren einer Eigenschaft, eines Felds oder eines verschachtelten Typs, die denselben Namen wie eine andere Eigenschaft, ein anderes Feld oder einen anderen verschachtelten Typ im selben besitzenden Typ hat.
  • Definieren von zwei lokalen Variablen im gleichen oder untergeordneten Bereich mit denselben Namen.

Unterstützen Sie unsere Publikation, indem Sie ihr folgen

Spring 3.0 und seine Funktionen Am häufigsten gestellte Java8-Stream-basierte Interviewfrage – Letzter Teil Semaphore | Java Concurrent API Wie ChatGPT SEO verändern wird: Vorteile und Herausforderungen Was Syntaxfehler verursacht und wie man sie vermeidet| Wie der Java-Compiler Syntaxfehler erkennt Der vollständige Leitfaden zum Aufbau einer White-Label-ICO-Plattform Als Fremder hat mir geholfen, die traurige Wahrheit der modernen Kommunikation zu verstehen. Die KI-Revolution: Wird KI der einzige Autor sein? Mittel? Ich habe nicht gesehen, dass ich ein Top-Autor auf Medium RestTemplate | bin FeignClient | WebClient mit Spring Boot So erstellen Sie ein einfaches Quarkus-Projekt mit Datenbankintegrationscodierung : Reduzieren Sie ein Array in Javascript, automatisieren Sie Social-Media-Marketing mit ChatGPT. 10 Widgets, die jeder Flutter-Entwickler beherrschen muss. Revolutionieren Sie Ihr Lernen mit Active Recall: Die bewährte Methode, um Informationen für die… aufzubewahren.