"Bună, Amigo! Să continuăm să vorbim despre greșeli. De data aceasta, vom explora greșelile cu care compilatorul nu te va ajuta întotdeauna. Fii atent și vei învăța ceva despre tine."

— Sunt gata să ascult, Diego. Sper că nu va fi prea jenant pentru mine.

Compararea obiectelor cu==

„Lista noastră de greșeli preferate ale programatorilor începători începe cu compararea obiectelor (în special șiruri de caractere) folosind operatorul ==

Exemplu:

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

"Am făcut asta destul de des. Acum pot vedea clar că acest cod nu va afișa niciodată "Șirurile sunt egale", deoarece instrucțiunea ifcompară referințe la două obiecte șir diferite."

„Da. De aceea varianta corectă ar fi:

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

Schimbarea unui Stringobiect

„Programatorii începători uită adesea că toate obiectele clasei sunt imuabile și că fiecare metodă a Stringclasei returnează un obiect nou - obiectul curent nu se schimbă niciodată.”

„Nu a fost cu mult timp în urmă când am învățat ce înseamnă imuabil , dar cred că am făcut asta.

„Sunt destul de sigur. Exemplu:

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

„Acest cod este foarte asemănător cu codul corect, dar nu va funcționa conform așteptărilor. Metoda toUpperCase()nu schimbă obiectul pe care este apelat. Codul corect ar arăta astfel:

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

"Exact. Am făcut asta, dar nici nu prea am înțeles ce e în neregulă. Mulțumesc pentru clarificare!"

Am uitat să inițializați obiectele care sunt elemente ale unui tablou

„O altă greșeală comună este să uitați să inițializați o variabilă matrice. Exemplu:

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

„Acest cod nu va funcționa: trebuie să setați în mod explicit variabila matricei egală cu o referință la obiectul container care va stoca elementele matricei. Versiunea corectă:

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

Folosind o variabilă locală în loc de o variabilă de instanță.

„Noilor începători nu le place să vină cu nume lungi și semnificative pentru variabile”.

„Este atât de adevărat. Pentru a face lucrurile rapid, uneori dau nume variabilelor precum a, b, și i”.

„Nu face asta. Este un lucru crud de făcut când codul are mai multe variabile de genul acesta:

Puneți numărul 99 în 100 de celule dintr-o matrice
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;
    }
  }
}

„Este mult mai dificil să faci greșeli în codul cu nume proprii. Versiunea corectă arată astfel:

Puneți numărul 99 în 100 de celule dintr-o matrice
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;
      }
   }
}

Eliminarea unui articol de colecție

— Te-ai uitat deja la colecții?

„Literal cu un singur ochi”.

„Dacă nu știi despre ce vorbesc, atunci fă-ți o notă pentru a arunca o privire în viitor. Foarte des sunt situații în care un anumit element trebuie eliminat dintr-o colecție. Codul arată aproximativ ca acest:

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

„Acest cod nu va funcționa, deoarece nu poți folosi o for-eachbuclă pentru a parcurge simultan elementele unei colecții și a modifica acea colecție.

„Există mai multe soluții. În primul rând, poți să parcurgi o colecție și să schimbi alta:

Soluția 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);

„În al doilea rând, începând cu Java 8, colecțiile au o removeIf()metodă, căreia îi poți transmite o regulă (funcția lambda) care indică ce elemente să elimini. Exemplu:

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

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

Plasarea mai multor clase cu publicmodificatorul într-un singur fișier

„Într-un fișier poate exista o singură clasă publică. Mai multe clase pot fi declarate într-un fișier, dar trebuie fie să fie clase interne ale unei clase publice, fie să nu aibă modificatorul. publicExemplu:

Conținutul fișierului Solution.java Notă
public class Solution
{
}
public class Main
{
}
Acest lucru nu este permis: două clase publice într-un singur fișier.
public class Solution
{
}
class Main
{
}
Dar poți face asta. Clasa principală nu este publică
public class Solution
{
  public static class Main
  {
  }
}
Și poți face asta. Clasa principală este o clasă imbricată

Apelarea metodelor obișnuite (non-statice) ale unei clase din main()metoda statică

„Uneori, programatorii începători încearcă să acceseze variabile și metode non-statice din main()metodă sau din alte metode statice. Un astfel de cod nu va funcționa, desigur.

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

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

mainMetoda se poate referi doar la metode/variabile statice. Ei bine, sau trebuie mai întâi să creeze o instanță a Solutionclasei și abia apoi să apeleze metode non-statice ale acelui obiect. Exemplu:

Soluția 1 Soluția 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();
  }
}

Declararea unui constructor ca o metodă

„O altă greșeală comună este declararea incorectă a unui constructor de clasă. Numele unui constructor trebuie să fie același cu numele clasei, iar un constructor nu are un tip de rezultat. Cele mai frecvente greșeli arată astfel:

public class Person
{
   private String value;

   void Person(String value)
   {
      this.value = value;
   }
}
Nu ar trebui să existe un tip de returnare aici
public class Person
{
   private String value;

   constructor(String value)
   {
      this.value = value;
   }
}
Numele constructorului este nevalid. Trebuie să se potrivească cu numele clasei
public class Person
{
   private String value;

   Person(String value)
   {
      value = value;
   }
}
this lipseste. Variabila valueva fi atribuită ei înșiși
public class Person
{
   private String value;

   Person(String value)
   {
      this.value = value;
   }
}
Totul este corect.

Moștenirea incorectă a interfețelor

„Creatorii Java au încercat să se apropie foarte mult de engleză, așa că au ales cuvinte cheie diferite pentru anumite concepte înrudite.

Când o clasă moștenește o clasă, trebuie să utilizați extendscuvântul cheie:

class Pet
{
}

class Cat extends Pet
{
}

„Când o clasă moștenește o interfață sau, mai precis, o implementează, trebuie să utilizați cuvântul implementscheie:

interface Meow
{
}

class Cat implements Meow
{
}

„Când o interfață moștenește o interfață, utilizați cuvântul extendscheie:

interface Meow
{
}

interface Voice extends Meov
{
}

Omițând breakîntr-o switchdeclarație

„Și ultima greșeală pentru astăzi, dar nu ultima pentru începători, este neincluderea unei breakdeclarații într-o switchdeclarație. Exemplu:

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

— Știi, Diego... Judecând după setul de erori pe care l-ai prezentat aici, parcă mi-ai citit jurnalul personal... Sau m-ai urmărit cum rezolv sarcini.

"Ha! Nu ai nicio îndoială. Am citit, urmărit și continui să fac asta. Așa că fii în alertă!"

"???"

"Nu-ți face griji. Glumesc. Fii vigilent și fă mai puține greșeli stupide."