„Hallo, Amigo! Lass uns weiter über Fehler reden. Dieses Mal werden wir Fehler untersuchen, bei denen dir der Compiler nicht immer weiterhilft. Pass auf und du wirst etwas über dich selbst lernen.“

„Ich bin bereit zuzuhören, Diego. Ich hoffe, das wird mir nicht zu peinlich.“

Vergleichen von Objekten mit==

„Unsere Liste der beliebtesten Fehler von Programmieranfängern beginnt mit dem Vergleich von Objekten (insbesondere Strings) mithilfe des ==Operators.“

Beispiel:

Scanner console = new Scanner(System.in);
String s1 = console.nextLine();
String s2 = console.nextLine();
if (s1 == s2)
{
   System.out.println("The strings are equal");
}

„Das habe ich ziemlich oft gemacht. Jetzt kann ich deutlich erkennen, dass dieser Code niemals „Die Zeichenfolgen sind gleich“ anzeigt, da die ifAnweisung Verweise auf zwei verschiedene Zeichenfolgenobjekte vergleicht.“

„Ja. Deshalb wäre die richtige Option:

Scanner console = new Scanner(System.in);
String s1 = console.nextLine();
String s2 = console.nextLine();
if (s1.equals(s2))
{
   System.out.println("The strings are equal");
}

StringEin Objekt ändern

„Neue Programmierer vergessen oft, dass alle Objekte der Klasse unveränderlich sind und dass jede Methode der StringKlasse ein neues Objekt zurückgibt – das aktuelle Objekt ändert sich nie.“

„Es ist noch nicht so lange her, dass ich gelernt habe, was unveränderlich bedeutet, aber ich glaube, ich habe es geschafft.“

„Da bin ich mir ziemlich sicher. Beispiel:

String s = "Hello";
s.toUpperCase (); // Convert to uppercase

„Dieser Code ist dem richtigen Code sehr ähnlich, funktioniert aber nicht wie erwartet. Die toUpperCase()Methode ändert das Objekt, für das sie aufgerufen wird, nicht. Der richtige Code würde so aussehen:

String s = "Hello";
String result = s.toUpperCase(); // Convert to uppercase

„Genau. Das habe ich getan, aber ich habe nicht einmal wirklich verstanden, was los war. Vielen Dank für die Klarstellung!“

Vergessen, Objekte zu initialisieren, die Elemente eines Arrays sind

„Ein weiterer häufiger Fehler besteht darin, zu vergessen, eine Array-Variable zu initialisieren. Beispiel:

int[] array;
array[0] = 1;
array[0] = 2;

„Dieser Code funktioniert nicht: Sie müssen die Array-Variable explizit auf einen Verweis auf das Containerobjekt setzen, das die Elemente des Arrays speichert. Richtige Version:

int[] array = new int[10];
array[0] = 1;
array[0] = 2;

Verwendung einer lokalen Variablen anstelle einer Instanzvariablen.

„Neulinge erfinden nicht gerne lange und aussagekräftige Namen für Variablen.“

„Das ist so wahr. Um Dinge schnell zu erledigen, gebe ich Variablen manchmal Namen wie a, bund i.“

„Tu das nicht. Das ist grausam, wenn der Code mehrere Variablen wie diese enthält:

Tragen Sie die Zahl 99 in 100 Zellen eines Arrays ein
class Solution
{
  public static int a = 99;
  public static int i = 100;

  public static void main(String[] args)
  {
    int[] a = new int[i];
    for (int i = 0; i < 10; i++)
    {
      a[i] = a;
    }
  }
}

„Es ist viel schwieriger, Fehler im Code mit Eigennamen zu machen. Die korrekte Version sieht so aus:

Tragen Sie die Zahl 99 in 100 Zellen eines Arrays ein
class Solution
{
   public static int value = 99;
   public static int count = 100;

   public static void main(String[] args)
   {
      int[] a = new int[count];
      for (int i = 0; i < 10; i++)
      {
         a[i] = value;
      }
   }
}

Entfernen eines Sammlungselements

„Haben Sie schon einmal in Sammlungen geschaut?“

„Im wahrsten Sinne des Wortes mit nur einem Auge.“

„Wenn Sie nicht wissen, wovon ich spreche, dann machen Sie sich eine Notiz, um in Zukunft einen Blick darauf zu werfen. Sehr oft gibt es Situationen, in denen ein bestimmtes Element aus einer Sammlung entfernt werden muss. Der Code sieht ungefähr so ​​aus Das:

ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 0, -5, -7, -12, 5, 15);

for (Integer value: list)
   if (value < 0)
      list.remove(value);

„Dieser Code funktioniert nicht, da Sie eine for-eachSchleife nicht verwenden können, um gleichzeitig die Elemente einer Sammlung zu durchlaufen und diese Sammlung zu ändern.

„Es gibt mehrere Lösungen. Erstens können Sie eine Sammlung durchlaufen und eine andere ändern:

Lösung 1
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 0, -5, -7, -12, 5, 15);

ArrayList<Integer> copy = new ArrayList<Integer>(list);
for (Integer value: copy)
   if (value < 0)
      list.remove(value);

„Zweitens verfügen Sammlungen seit Java 8 über eine removeIf()Methode, an die Sie eine Regel (Lambda-Funktion) übergeben können, die angibt, welche Elemente entfernt werden sollen. Beispiel:

Lösung 2
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 0, -5, -7, -12, 5, 15);

list.removeIf( x-> x<0 );

Platzieren mehrerer Klassen mit dem publicModifikator in einer einzigen Datei

„Eine Datei kann nur eine öffentliche Klasse enthalten. In einer Datei können mehrere Klassen deklariert werden, diese müssen jedoch entweder innere Klassen einer öffentlichen Klasse sein oder dürfen nicht über den Modifikator verfügen. publicBeispiel:

Inhalt der Solution.java-Datei Notiz
public class Solution
{
}
public class Main
{
}
Dies ist nicht zulässig: zwei öffentliche Klassen in einer einzigen Datei.
public class Solution
{
}
class Main
{
}
Aber Sie können dies tun. Die Main-Klasse ist nicht öffentlich
public class Solution
{
  public static class Main
  {
  }
}
Und Sie können dies tun. Die Hauptklasse ist eine verschachtelte Klasse

Aufrufen gewöhnlicher (nicht statischer) Methoden einer Klasse über die statische main()Methode

„Manchmal versuchen Programmieranfänger, über die main()Methode oder andere statische Methoden auf nicht statische Variablen und Methoden zuzugreifen. Solcher Code funktioniert natürlich nicht.“

public class Solution
{
   public int n = 100;
   public int[] createArray()
   {
      return new int[n];
   }

   public static void main(String[]args)
   {
      int[] array = createArray();
   }
}

„Die mainMethode kann nur auf statische Methoden/Variablen verweisen. Nun, oder sie muss zuerst eine Instanz der SolutionKlasse erstellen und erst dann nicht statische Methoden dieses Objekts aufrufen. Beispiel:

Lösung 1 Lösung 2
public class Solution
{
  public static int n = 100;

  public static int[] createArray()
  {
    return new int[n];
  }

  public static void main(String[]args)
  {
    int[] array = createArray();
  }
}
public class Solution
{
  public int n = 100;

  public int[] createArray()
  {
    return new int[n];
  }

  public static void main(String[]args)
  {
    Solution sol = new Solution();
    int[] array = sol.createArray();
  }
}

Einen Konstruktor wie eine Methode deklarieren

„Ein weiterer häufiger Fehler ist die falsche Deklaration eines Klassenkonstruktors. Der Name eines Konstruktors muss mit dem Namen der Klasse identisch sein, und ein Konstruktor hat keinen Ergebnistyp. Die häufigsten Fehler sehen so aus:

public class Person
{
   private String value;

   void Person(String value)
   {
      this.value = value;
   }
}
Hier sollte kein Rückgabetyp vorhanden sein
public class Person
{
   private String value;

   constructor(String value)
   {
      this.value = value;
   }
}
Der Konstruktorname ist ungültig. Es muss mit dem Klassennamen übereinstimmen
public class Person
{
   private String value;

   Person(String value)
   {
      value = value;
   }
}
this wird vermisst. Die valueVariable wird sich selbst zugewiesen
public class Person
{
   private String value;

   Person(String value)
   {
      this.value = value;
   }
}
Das ist alles richtig.

Falsche Vererbung von Schnittstellen

„Die Entwickler von Java haben versucht, es dem Englischen sehr nahe zu bringen, deshalb haben sie für bestimmte verwandte Konzepte unterschiedliche Schlüsselwörter gewählt.

Wenn eine Klasse eine Klasse erbt, müssen Sie das extendsSchlüsselwort verwenden:

class Pet
{
}

class Cat extends Pet
{
}

„Wenn eine Klasse eine Schnittstelle erbt oder genauer gesagt implementiert, müssen Sie das implementsSchlüsselwort verwenden:

interface Meow
{
}

class Cat implements Meow
{
}

„Wenn eine Schnittstelle eine Schnittstelle erbt, verwenden Sie das extendsSchlüsselwort:

interface Meow
{
}

interface Voice extends Meov
{
}

breakIn einer switchAussage weglassen

„Und der letzte Fehler für heute, aber nicht der letzte für Anfänger, besteht darin, eine breakAussage nicht in eine switchAussage aufzunehmen. Beispiel:

Falsch Rechts
LocalDate date = LocalDate.now();
DayOfWeek day = date.getDayOfWeek();
switch (day)
{
   case MONDAY:
      System.out.println("Monday");
   case TUESDAY:
      System.out.println("Tuesday");
   case WEDNESDAY:
      System.out.println("Wednesday");
   case THURSDAY:
      System.out.println("Thursday");
   case FRIDAY:
      System.out.println("Friday");
   case SATURDAY:
      System.out.println("Saturday");
   case SUNDAY:
      System.out.println("Sunday");
}
LocalDate date = LocalDate.now();
DayOfWeek day = date.getDayOfWeek();
switch (day)
{
   case MONDAY:
      System.out.println("Monday");
      break;
   case TUESDAY:
      System.out.println("Tuesday");
      break;
   case WEDNESDAY:
      System.out.println("Wednesday");
      break;
   case THURSDAY:
      System.out.println("Thursday");
      break;
   case FRIDAY:
      System.out.println("Friday");
      break;
   case SATURDAY:
      System.out.println("Saturday");
      break;
   case SUNDAY:
      System.out.println("Sunday");
      break;
}

„Weißt du, Diego... Den Fehlern nach zu urteilen, die du hier präsentiert hast, fühlt es sich an, als hättest du mein persönliches Tagebuch gelesen... Oder du hättest mir beim Lösen von Aufgaben zugeschaut.“

„Ha! Daran besteht kein Zweifel. Ich habe gelesen, verfolgt und tue dies auch weiterhin. Seien Sie also auf der Hut!“

„???“

„Mach dir keine Sorgen. Ich mache nur Spaß. Sei wachsam und mache weniger dumme Fehler.“