"Hallo, Amigo! Laten we doorgaan met praten over fouten. Deze keer zullen we fouten onderzoeken waar de compiler je niet altijd mee zal helpen. Let goed op en je leert iets over jezelf."

'Ik ben klaar om te luisteren, Diego. Ik hoop dat dit niet te gênant voor me zal zijn.'

Objecten vergelijken met==

"Onze lijst met de beste programmeerfouten voor beginnende programmeurs begint met het vergelijken van objecten (vooral strings) met behulp van de ==operator"

Voorbeeld:

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

"Dat heb ik vrij vaak gedaan. Nu kan ik duidelijk zien dat deze code nooit "The strings are equal" zal weergeven, omdat de ifinstructie referenties naar twee verschillende stringobjecten vergelijkt.

"Ja. Daarom zou de juiste optie zijn:

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

StringEen voorwerp veranderen

"Nieuwe programmeurs vergeten vaak dat alle objecten van de klasse onveranderlijk zijn en dat elke methode van de Stringklasse een nieuw object retourneert - het huidige object verandert nooit."

"Het is nog niet zo lang geleden dat ik leerde wat onveranderlijk betekent, maar ik denk dat ik dit heb gedaan.

"Ik ben er vrij zeker van. Voorbeeld:

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

"Deze code lijkt sterk op correcte code, maar werkt niet zoals verwacht. De toUpperCase()methode verandert het object waarop het wordt aangeroepen niet. De juiste code ziet er als volgt uit:

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

"Precies. Dat heb ik gedaan, maar ik begreep niet eens wat er aan de hand was. Bedankt voor de opheldering!"

Vergeten objecten te initialiseren die elementen van een array zijn

"Een andere veelgemaakte fout is vergeten een arrayvariabele te initialiseren. Voorbeeld:

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

"Deze code werkt niet: je moet de arrayvariabele expliciet gelijk stellen aan een verwijzing naar het containerobject dat de elementen van de array zal opslaan. Correcte versie:

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

Een lokale variabele gebruiken in plaats van een instantievariabele.

"Nieuwkomers houden er niet van om lange en betekenisvolle namen voor variabelen te bedenken."

"Dat is zo waar. Om dingen snel gedaan te krijgen, geef ik variabelen soms namen als a, b, en i."

"Doe dat niet. Dat is wreed om te doen als de code meerdere van dat soort variabelen heeft:

Zet het getal 99 in 100 cellen van een array
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;
    }
  }
}

"Het is veel moeilijker om fouten te maken in code met eigennamen. De juiste versie ziet er zo uit:

Zet het getal 99 in 100 cellen van een array
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;
      }
   }
}

Een collectie-item verwijderen

"Heb je al in collecties gekeken?"

"Letterlijk met slechts één oog."

"Als je niet weet waar ik het over heb, maak dan een notitie voor jezelf om in de toekomst te kijken. Heel vaak zijn er situaties waarin een bepaald element uit een verzameling moet worden verwijderd. De code ziet er ongeveer zo uit als dit:

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

"Deze code werkt niet, omdat je geen for-eachlus kunt gebruiken om tegelijkertijd door de elementen van een verzameling te lopen en die verzameling te wijzigen.

"Er zijn verschillende oplossingen. Ten eerste kun je de ene collectie doorlopen en een andere wijzigen:

Oplossing 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);

"Ten tweede hebben verzamelingen sinds Java 8 een removeIf()methode waaraan je een regel (lambda-functie) kunt doorgeven die aangeeft welke elementen moeten worden verwijderd. Voorbeeld:

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

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

Meerdere klassen met de publicmodifier in één bestand plaatsen

"Er kan slechts één openbare klasse in een bestand zijn. Er kunnen meer klassen in een bestand worden gedeclareerd, maar het moeten ofwel innerlijke klassen van een openbare klasse zijn, of ze moeten niet de publicmodifier hebben. Voorbeeld:

Inhoud van het Solution.java-bestand Opmerking
public class Solution
{
}
public class Main
{
}
Dit mag niet: twee publieke klassen in één bestand.
public class Solution
{
}
class Main
{
}
Maar je kunt dit doen. De hoofdklasse is niet openbaar
public class Solution
{
  public static class Main
  {
  }
}
En jij kunt dit. De klasse Main is een geneste klasse

Gewone (niet-statische) methoden van een klasse aanroepen vanuit de statische main()methode

"Soms proberen beginnende programmeurs toegang te krijgen tot niet-statische variabelen en methoden van de main()methode of andere statische methoden. Dergelijke code zal natuurlijk niet werken.

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

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

"De mainmethode kan alleen verwijzen naar statische methoden/variabelen. Welnu, of het moet eerst een instantie van de Solutionklasse maken en pas daarna niet-statische methoden van dat object aanroepen. Voorbeeld:

Oplossing 1 Oplossing 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();
  }
}

Een constructor declareren als een methode

"Een andere veelgemaakte fout is het onjuist declareren van een klassenconstructor. De naam van een constructor moet hetzelfde zijn als de naam van de klasse, en een constructor heeft geen resultaattype. De meest voorkomende fouten zien er als volgt uit:

public class Person
{
   private String value;

   void Person(String value)
   {
      this.value = value;
   }
}
Er zou hier geen retourtype moeten zijn
public class Person
{
   private String value;

   constructor(String value)
   {
      this.value = value;
   }
}
De constructornaam is ongeldig. Het moet overeenkomen met de klassenaam
public class Person
{
   private String value;

   Person(String value)
   {
      value = value;
   }
}
this ontbreekt. De valuevariabele wordt aan zichzelf toegewezen
public class Person
{
   private String value;

   Person(String value)
   {
      this.value = value;
   }
}
Dat klopt allemaal.

Onjuiste overerving van interfaces

"De makers van Java probeerden het heel dicht bij het Engels te brengen, dus kozen ze andere trefwoorden voor bepaalde verwante concepten.

Wanneer een klasse een klasse overerft, moet u het extendstrefwoord gebruiken:

class Pet
{
}

class Cat extends Pet
{
}

implements"Als een klasse een interface erft, of beter gezegd, deze implementeert, moet je het trefwoord gebruiken :

interface Meow
{
}

class Cat implements Meow
{
}

"Wanneer een interface een interface erft, gebruik dan het extendstrefwoord:

interface Meow
{
}

interface Voice extends Meov
{
}

Weglaten breakin een switchverklaring

"En de laatste fout voor vandaag, maar niet de laatste voor beginners, is het niet opnemen van een breakverklaring in een switchverklaring. Voorbeeld:

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

'Weet je, Diego... te oordelen naar de reeks fouten die je hier hebt gemaakt, voelt het alsof je mijn persoonlijke dagboek hebt gelezen... of je hebt me taken zien oplossen.'

"Ha! Twijfel er niet aan. Ik heb het gelezen, gevolgd en blijf dit doen. Wees dus alert!"

"???"

'Maak je geen zorgen. Ik maak maar een grapje. Wees waakzaam en maak minder domme fouten.'