JavaRush /Java-Blog /Random-DE /Fehler von Anfänger-Java-Programmierern. Teil 1
articles
Level 15

Fehler von Anfänger-Java-Programmierern. Teil 1

Veröffentlicht in der Gruppe Random-DE

1. Der Name der Klasse unterscheidet sich vom Namen der Datei, in der sie gespeichert ist

Alle Java-Frameworks, die ich verwendet habe, einschließlich der Javasoft-JDKs, gehen davon aus, dass der Quellcode für eine Klasse mit dem öffentlichen Modifikator in einer Datei mit genau demselben Namen wie der Klassenname und der Erweiterung .java gespeichert ist. Die Nichtbeachtung dieser Konvention kann viele Probleme verursachen, die während der Kompilierung auftreten.
Fehler von Anfänger-Java-Programmierern.  Teil 1 - 1
Anfänger (Programmierer) vergessen diese Konvention oft und legen beispielsweise den Dateinamen entsprechend der Aufgabenstellung fest: Lab6.java. Falsches Beispiel: DateinameLab6.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Korrigiertes Beispiel: DateinameAirplane.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Bitte beachten Sie:Es wird davon ausgegangen, dass der Klassenname mit einem Großbuchstaben beginnt. Betriebssysteme, bei denen bei Dateinamen die Groß-/Kleinschreibung beachtet wird, können zusätzliche Probleme darstellen, insbesondere für Studenten, die Java unter Unix lernen und mit dem DOS-Dateibenennungssystem vertraut sind. Die Klasse MotorVehiclesollte in einer Datei gespeichert werden MotorVehicle.java, jedoch nicht in einer motorvehicle.java.

2. Vergleich mit==

In Java sind Strings Objekte der Klasse java.lang.String. Der auf Objekte angewendete Operator ==prüft die Gleichheit von Referenzen auf Objekte! Manchmal verstehen Schüler die Semantik des Operators nicht ==und versuchen, ihn zum Vergleichen von Zeichenfolgen zu verwenden. Falsches Beispiel:
// проверим, gleicht ли первый аргумент "-a"
if (args[0] == "-a") {
    optionsAll = true;
}
Der richtige Weg, zwei Zeichenfolgen auf Gleichheit zu vergleichen, ist die Verwendung der equals()Klassenmethode java.lang.String. Es wird zurückgegeben true, wenn die Zeichenfolgen dieselbe Länge haben und dieselben Zeichen enthalten. (Hinweis: Tatsächlich ist dies keine Garantie für Gleichheit. Tatsächlich equalswird geprüft, ob zwei Zeichenfolgen Zeichen für Zeichen gleich sind.) Korrigiertes Beispiel:
//  проверим, gleicht ли первый аргумент "-a"
if ("-a".equals(args[0])) {
    optionsAll = true;
}
Dieser Fehler ist dumm, denn tatsächlich stellt sich heraus, dass der Java-Code syntaktisch korrekt ist, aber am Ende funktioniert er nicht wie erwartet. Einige Schüler versuchen auch , die Vergleichsoperatoren >und anstelle der <=Klassenmethode zu verwenden . Dieser Fehler ist leichter zu erkennen, da er während der Kompilierungsphase Fehler verursacht. compareTo()java.lang.String

3. Ich habe vergessen, Objekte zu initialisieren, die Elemente des Arrays sind.

In Java ist ein Array von Objekten eigentlich ein Array von Objektreferenzen. Beim Erstellen eines Arrays wird lediglich eine Reihe von Referenzen erstellt, die auf nichts verweisen (d. h. sie sind null). Um tatsächlich ein „vollständiges“ Array von Objekten zu erstellen, müssen Sie jedes Element des Arrays initialisieren. Viele Studierende verstehen das nicht; Sie glauben, dass sie durch die Erstellung einer Reihe von Objekten automatisch die Objekte selbst erstellen. (In den meisten Fällen bringen die Schüler dieses Konzept aus C++ mit, wo das Erstellen eines Arrays von Objekten dazu führt, dass die Objekte selbst durch Aufrufen ihres Standardkonstruktors erstellt werden.) Im folgenden Beispiel möchte der Schüler drei Objekte der Klasse erstellen StringBuffer. Der Code wird fehlerfrei kompiliert, es tritt jedoch in der letzten Zeile eine Ausnahme auf NullPointerException, in der auf ein nicht vorhandenes Objekt zugegriffen wird. Falsches Beispiel:
// Создаем массив из StringBuffer
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
myTempBuffers[0].add(data);
Um diesen Fehler zu vermeiden, müssen Sie daran denken, die Array-Elemente zu initialisieren. Korrigiertes Beispiel:
// Создаем массив из StringBuffer и инициализируем элементы
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
for (int ix = 0; ix < myTempBuffers.length; ix++)
     myTempBuffers[ix] = new StringBuffer();

myTempBuffers[0].add(data);

4. Mehrere Klassen mit einem Modifikator gleichzeitig in einer Datei platzierenpublic

Java-Quelldateien sind auf bestimmte Weise mit den in diesen Dateien enthaltenen Klassen verknüpft. Die Beziehung lässt sich wie folgt charakterisieren: Jede Java-Klasse wird in maximal einer Datei gespeichert. In jeder Quellcodedatei können Sie nicht mehr als eine Klasse mit dem Modifikator platzieren public. Wenn in der Quellcodedatei eine Klasse mit einem Modifikator vorhanden ist public, müssen der Dateiname und der Klassenname unbedingt identisch sein (Übersetzungshinweis: bis zur Groß-/Kleinschreibung, siehe Punkt 1). Manchmal vergessen Schüler die 2. Regel, was zu Fehlern führt bei der Bühnenzusammenstellung. Die Fehlermeldung für die 2. und 3. Regel ist dieselbe (was es eigentlich schwierig macht, diesen Fehler zu erkennen).

5. Ersetzung eines Klassenfeldes durch eine lokale Variable.

Mit Java können Sie Variablen innerhalb einer Methode deklarieren, deren Name mit den Feldern der Klasse übereinstimmt. In diesem Fall haben lokale Variablen Vorrang und werden anstelle von Feldern verwendet. Der Compiler gibt einen Fehler aus, wenn Variablen mit demselben Namen unterschiedliche Typen haben. Wenn es sich um denselben Typ handelt, liegt kein Kompilierungsfehler vor und die Gründe für die fehlerhafte Ausführung des Programms sind unklar. Falsches Beispiel:
public class Point3 {
    int i = 0;
    int j = 0;
    int k = 0;

    public boolean hits(Point[] p2list) {
      for(int i = 0; i < p2list.length; i++) {
        Point p2 = p2list[i];
        if (p2.x == i && p2.y == j)
          return true;
      }
      return false;
    }
}
Es gibt mehrere Möglichkeiten, diesen Fehler zu beheben. Am einfachsten ist es, über einen impliziten Zeiger auf Klassenfelder zuzugreifen this: this.Name_поля. Am besten benennen Sie das Klassenfeld oder die lokale Variable um, dann findet keine Ersetzung statt. (ungefähr übersetzt: Die 2. Methode ist nicht unsere Methode. Außerdem ist sie keine Garantie dafür, dass ich nicht eines Tages versehentlich ein Feld einer Variablen ersetze. Eine noch größere Schwierigkeit entsteht bei der Vererbung, wenn ich überhaupt nicht sehe, welche Felder die Klasse hat ) Korrigiertes Beispiel:
// One way to fix the problem
  int i = 0;
  int j = 0;
  int k = 0;

  public boolean hits(Point[] p2list) {
    for(int i = 0; i < p2list.length; i++) {
      Point p2 = p2list[i];
      if (p2.x == this.i && p2.y == this.j)
        return true;
    }
    return false;
  }

  // *****************************
  // Лучший способ
  int x = 0;
  int y = 0;
  int z = 0;

  public boolean hits(Point[] p2list) {
    for(int i = 0; i < p2list.length; i++) {
      Point p2 = p2list[i];
      if (p2.x == x && p2.y == y)
        return true;
    }
    return false;
  }
Dieser Fehler kann auch auftreten, wenn der Name des Methodenparameters mit dem Namen des Klassenfelds identisch ist. Das sieht in Konstruktoren gut aus, ist aber für normale Methoden nicht geeignet.

ca. Übersetzung

ein wenig chaotisch, aber das ist das Wesentliche

public class Test {
   private int param = 0;

   public Test(int param) {
      this.param = param;
   }
}

Das heißt, im Konstruktor sieht alles schön aus, aber dies sollte nicht für gewöhnliche Methoden verwendet werden.

6. Ich habe vergessen, den übergeordneten Konstruktor (Superklasse) aufzurufen

Wenn eine Klasse eine andere Klasse erweitert, muss jeder Unterklassenkonstruktor einen Oberklassenkonstruktor aufrufen. Dies wird normalerweise dadurch erreicht, dass der Superklassenkonstruktor mit der Methode aufgerufen wird, die super(x)in der ersten Zeile des Konstruktors steht. Steht in der ersten Zeile des Konstruktors kein Aufruf super(x), fügt der Compiler selbst diesen Aufruf ein, allerdings ohne Parameter: super(). (ungefähr übersetzt: x...se, aber ich wusste es nicht) Manchmal vergessen Studierende diese Anforderung. Normalerweise stellt dies kein Problem dar: Der Aufruf des Superklassenkonstruktors wird vom Compiler eingefügt und alles funktioniert einwandfrei. Wenn die Oberklasse jedoch keinen Standardkonstruktor hat, gibt der Compiler einen Fehler aus. Im folgenden Beispiel java.io.Filehaben alle Konstruktoren der Oberklasse 1 oder 2 Parameter: Fehlerhaftes Beispiel:
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        classname = cl;
    }
}
Die Lösung des Problems besteht darin, einen expliziten Aufruf an den richtigen Superklassenkonstruktor einzufügen: Korrigiertes Beispiel:
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        super(cl + ".class");
        classname = cl;
    }
}
Eine unangenehmere Situation tritt auf, wenn die Superklasse über einen Standardkonstruktor verfügt, dieser das Objekt jedoch nicht vollständig initialisiert. In diesem Fall wird der Code kompiliert, aber die Ausgabe des Programms ist möglicherweise falsch oder es tritt eine Ausnahme auf.

7. Fehlerhaftes Abfangen von Ausnahmen

Das Ausnahmebehandlungssystem von Java ist recht leistungsfähig, aber für Anfänger schwer zu verstehen. Studierende, die C++ oder Ada beherrschen, haben in der Regel nicht die gleichen Schwierigkeiten wie C- und Fortran-Programmierer. Die folgenden Beispiele zeigen einige häufige Fehler. In diesem Beispiel wird die Ausnahme nicht benannt. Der Compiler zeigt diesen Fehler in der Kompilierungsphase an, sodass Sie ihn leicht selbst beheben können. Falsches Beispiel:
try {
    stream1 = new FileInputStream("data.txt");
} catch (IOException) {
    message("Could not open data.txt");
}
Korrigiertes Beispiel:
try {
   stream1 = new FileInputStream("data.txt");
} catch (IOException ie) {
   message("Could not open data.txt: " + ie);
}
Die Reihenfolge der Blöcke catchbestimmt die Reihenfolge, in der Ausnahmen abgefangen werden. Es muss berücksichtigt werden, dass jeder dieser Blöcke alle Ausnahmen der angegebenen Klasse oder einer ihrer Unterklassen abfängt. Wenn Sie dies nicht berücksichtigen, kann es zu einem nicht erreichbaren Catch-Block kommen, auf den der Compiler Sie hinweist. Im folgenden Beispiel SocketExceptionhandelt es sich um eine Unterklasse von IOException. Falsches Beispiel:
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (IOException ie) {
    message("Error accepting connection.");
} catch (SocketException se) {
    message("Error setting time-out.");
}
Korrigiertes Beispiel:
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (SocketException se) {
    message("Error setting time-out.");
} catch (IOException ie) {
    message("Error accepting connection.");
}
Wenn in Ihrem Code eine Ausnahme auftreten kann, die von keinem Block abgefangen wird try-catch, sollte diese Ausnahme im Methodenheader deklariert werden. ( Für Ausnahmen – Unterklassen einer Klasse – RuntimeExceptionist dies nicht erforderlich ). Schüler vergessen manchmal, dass der Aufruf einer Methode eine Ausnahme auslösen kann. Der einfachste Weg, dies zu beheben, besteht darin, den Methodenaufruf in einen Block zu stellen try-catch. Falsches Beispiel:
public void waitFor(int sec) {
    Thread.sleep(sec * 1000);
}
Korrigiertes Beispiel:
public void waitFor(int sec) throws InterruptedException {
    Thread.sleep(sec * 1000);
}

8. Die Zugriffsmethode hat einen Typvoid

Das ist ein ganz einfacher Fehler. Der Student erstellt eine Methode für den Zugriff auf eine Variable, gibt jedoch an, dass die Methode nichts zurückgibt (fügt einen Modifikator voidin den Methodenheader ein). Um diesen Fehler zu beheben, müssen Sie den richtigen Rückgabetyp angeben. Falsches Beispiel:
public class Line {
    private Point start, end;
    public void getStart() {
      return start;
    }
}
Korrigiertes Beispiel:
public class Line {
    private Point start, end;
    public Point getStart() {
      return start;
    }
}
Die Angabe des falschen Rückgabetyps führt zu einer ganzen Klasse von Fehlern. Normalerweise erkennt der Compiler diese Fehler und meldet sie, damit die Schüler sie selbst korrigieren können. Autor: A. Grasoff™ Fortsetzung lesen Link zur Quelle: Fehler von Java-Programmieranfängern
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION