"Ciao, Amigo! Continuiamo a parlare di errori. Questa volta esploreremo errori con cui il compilatore non sempre ti aiuterà. Presta attenzione e imparerai qualcosa su te stesso."

"Sono pronto ad ascoltare, Diego. Spero che questo non sia troppo imbarazzante per me."

Confrontare gli oggetti con==

"La nostra lista dei principali errori preferiti dei programmatori principianti inizia con il confronto di oggetti (in particolare stringhe) utilizzando l' ==operatore"

Esempio:

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

"L'ho fatto abbastanza spesso. Ora posso vedere chiaramente che questo codice non visualizzerà mai "Le stringhe sono uguali", perché l' ifistruzione confronta i riferimenti a due diversi oggetti stringa."

"Sì. Ecco perché l'opzione corretta sarebbe:

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

Modificare un Stringoggetto

"I programmatori principianti spesso dimenticano che tutti gli oggetti della classe sono immutabili e che ogni metodo della Stringclasse restituisce un nuovo oggetto: l'oggetto corrente non cambia mai."

"Non è passato molto tempo da quando ho imparato cosa significa immutabile , ma penso di averlo fatto.

"Ne sono abbastanza sicuro. Esempio:

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

"Questo codice è molto simile al codice corretto, ma non funzionerà come previsto. Il toUpperCase()metodo non modifica l'oggetto su cui viene chiamato. Il codice corretto sarebbe simile al seguente:

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

"Esattamente. L'ho fatto, ma non ho nemmeno capito bene cosa c'era che non andava. Grazie per il chiarimento!"

Dimenticare di inizializzare oggetti che sono elementi di un array

"Un altro errore comune è dimenticare di inizializzare una variabile di matrice. Esempio:

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

"Questo codice non funzionerà: è necessario impostare in modo esplicito la variabile array uguale a un riferimento all'oggetto contenitore che memorizzerà gli elementi dell'array. Versione corretta:

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

Utilizzo di una variabile locale invece di una variabile di istanza.

"Ai neofiti non piace inventare nomi lunghi e significativi per le variabili."

"È così vero. Per fare le cose velocemente, a volte do nomi di variabili come a, be i."

"Non farlo. È una cosa crudele da fare quando il codice ha diverse variabili come questa:

Inserisci il numero 99 in 100 celle di un 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;
    }
  }
}

"È molto più difficile commettere errori nel codice con nomi propri. La versione corretta è questa:

Inserisci il numero 99 in 100 celle di un 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;
      }
   }
}

Rimozione di un elemento della raccolta

"Hai già esaminato le collezioni?"

"Letteralmente con un occhio solo."

"Se non sai di cosa sto parlando, prendi nota di dare un'occhiata in futuro. Molto spesso ci sono situazioni in cui un determinato elemento deve essere rimosso da una raccolta. Il codice sembra più o meno come Questo:

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

"Questo codice non funzionerà, perché non è possibile utilizzare un for-eachciclo per attraversare simultaneamente gli elementi di una raccolta e modificare tale raccolta.

"Esistono diverse soluzioni. Innanzitutto, puoi attraversare una raccolta e modificarne un'altra:

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

"In secondo luogo, a partire da Java 8, le raccolte hanno un removeIf()metodo, al quale è possibile passare una regola (funzione lambda) che indica quali elementi rimuovere. Esempio:

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

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

Inserimento di più classi con il publicmodificatore in un singolo file

"Può esserci solo una classe pubblica in un file. È possibile dichiarare più classi in un file, ma devono essere classi interne di una classe pubblica o non avere il publicmodificatore. Esempio:

Contenuto del file Solution.java Nota
public class Solution
{
}
public class Main
{
}
Questo non è consentito: due classi pubbliche in un unico file.
public class Solution
{
}
class Main
{
}
Ma puoi farlo. La classe principale non è pubblica
public class Solution
{
  public static class Main
  {
  }
}
E puoi farlo. La classe Main è una classe nidificata

Chiamare metodi ordinari (non statici) di una classe dal main()metodo statico

"A volte i programmatori principianti cercano di accedere a variabili e metodi non statici dal main()metodo o da altri metodi statici. Tale codice non funzionerà, ovviamente.

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

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

"Il mainmetodo può fare riferimento solo a metodi/variabili statici. Bene, oppure deve prima creare un'istanza della Solutionclasse e solo successivamente chiamare metodi non statici di quell'oggetto. Esempio:

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

Dichiarare un costruttore come un metodo

"Un altro errore comune è la dichiarazione errata di un costruttore di classe. Il nome di un costruttore deve essere uguale al nome della classe e un costruttore non ha un tipo di risultato. Gli errori più comuni sono simili a questi:

public class Person
{
   private String value;

   void Person(String value)
   {
      this.value = value;
   }
}
Non dovrebbe esserci un tipo di ritorno qui
public class Person
{
   private String value;

   constructor(String value)
   {
      this.value = value;
   }
}
Il nome del costruttore non è valido. Deve corrispondere al nome della classe
public class Person
{
   private String value;

   Person(String value)
   {
      value = value;
   }
}
this manca. La valuevariabile verrà assegnata a se stessa
public class Person
{
   private String value;

   Person(String value)
   {
      this.value = value;
   }
}
È tutto corretto.

Ereditarietà errata delle interfacce

"I creatori di Java hanno cercato di renderlo molto vicino all'inglese, quindi hanno scelto parole chiave diverse per alcuni concetti correlati.

Quando una classe eredita una classe, devi usare la extendsparola chiave:

class Pet
{
}

class Cat extends Pet
{
}

"Quando una classe eredita un'interfaccia, o, più precisamente, la implementa, è necessario utilizzare la implementsparola chiave:

interface Meow
{
}

class Cat implements Meow
{
}

"Quando un'interfaccia eredita un'interfaccia, usa la extendsparola chiave:

interface Meow
{
}

interface Voice extends Meov
{
}

Omissione breakin una switchdichiarazione

"E l'ultimo errore di oggi, ma non l'ultimo per i principianti, è non includere un'affermazione breakin switchun'affermazione. Esempio:

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

"Sai, Diego... A giudicare dalla serie di errori che hai presentato qui, sembra che tu stia leggendo il mio diario personale... O che mi stia guardando risolvere compiti."

"Ah! Non dubitare. Ho letto, tracciato e continuo a farlo. Quindi stai all'erta!"

"???"

"Non preoccuparti. Sto solo scherzando. Sii vigile e fai meno errori stupidi."