„Cześć, Amigo! Porozmawiajmy dalej o błędach. Tym razem przyjrzymy się błędom, z którymi kompilator nie zawsze ci pomoże. Uważaj, a dowiesz się czegoś o sobie”.

„Jestem gotów słuchać, Diego. Mam nadzieję, że nie będzie to dla mnie zbyt krępujące”.

Porównywanie obiektów z==

„Nasza lista najczęstszych błędów początkujących programistów zaczyna się od porównania obiektów (zwłaszcza ciągów znaków) za pomocą ==operatora”

Przykład:

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

„Robiłem to dość często. Teraz wyraźnie widzę, że ten kod nigdy nie wyświetli komunikatu „Struny są równe”, ponieważ instrukcja ifporównuje odwołania do dwóch różnych obiektów łańcuchowych”.

„Tak. Dlatego poprawną opcją byłoby:

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

Zmiana Stringobiektu

„Początkujący programiści często zapominają, że wszystkie obiekty klasy są niezmienne i że każda metoda klasy Stringzwraca nowy obiekt – bieżący obiekt nigdy się nie zmienia”.

„Nie tak dawno temu dowiedziałem się, co oznacza niezmienność , ale myślę, że to zrobiłem.

„Jestem tego całkiem pewien. Przykład:

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

„Ten kod jest bardzo podobny do poprawnego kodu, ale nie będzie działał zgodnie z oczekiwaniami. Metoda toUpperCase()nie zmienia obiektu, na którym jest wywoływana. Prawidłowy kod wyglądałby tak:

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

„Dokładnie. Zrobiłem to, ale nawet tak naprawdę nie rozumiałem, co jest nie tak. Dziękuję za wyjaśnienie!”

Zapominanie o zainicjowaniu obiektów, które są elementami tablicy

„Innym częstym błędem jest zapominanie o zainicjowaniu zmiennej tablicowej. Przykład:

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

„Ten kod nie zadziała: musisz jawnie ustawić zmienną tablicową równą odwołaniu do obiektu kontenera, który będzie przechowywać elementy tablicy. Poprawna wersja:

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

Używanie zmiennej lokalnej zamiast zmiennej instancji.

„Początkujący nie lubią wymyślać długich i znaczących nazw zmiennych”.

„To prawda. Aby szybko załatwić sprawę, czasami nadaję zmiennym nazwy takie jak a, b, i i”.

„Nie rób tego. To okrutne, gdy kod ma kilka takich zmiennych:

Umieść liczbę 99 w 100 komórkach tablicy
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;
    }
  }
}

„O wiele trudniej jest popełnić błąd w kodzie z nazwami własnymi. Poprawna wersja wygląda tak:

Umieść liczbę 99 w 100 komórkach tablicy
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;
      }
   }
}

Usuwanie elementu kolekcji

– Czy przejrzałeś już kolekcje?

„Dosłownie jednym okiem”.

„Jeśli nie wiesz, o czym mówię, to zanotuj sobie, żeby spojrzeć na przyszłość. Bardzo często zdarzają się sytuacje, kiedy jakiś element trzeba usunąć z kolekcji. Kod wygląda z grubsza tak Ten:

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

„Ten kod nie zadziała, ponieważ nie można użyć pętli for-eachdo jednoczesnego przeglądania elementów kolekcji i modyfikowania tej kolekcji.

„Istnieje kilka rozwiązań. Po pierwsze, możesz przejść przez jedną kolekcję i zmienić inną:

Rozwiązanie 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);

„Po drugie, od Javy 8 kolekcje mają removeIf()metodę, do której można przekazać regułę (funkcja lambda) wskazującą, które elementy należy usunąć. Przykład:

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

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

Umieszczenie kilku klas z publicmodyfikatorem w jednym pliku

„W pliku może być tylko jedna klasa publiczna. W pliku można zadeklarować więcej klas, ale muszą to być wewnętrzne klasy klasy publicznej lub nie mieć modyfikatora. Przykład public:

Zawartość pliku Solution.java Notatka
public class Solution
{
}
public class Main
{
}
To jest niedozwolone: ​​dwie klasy publiczne w jednym pliku.
public class Solution
{
}
class Main
{
}
Ale możesz to zrobić. Klasa główna nie jest publiczna
public class Solution
{
  public static class Main
  {
  }
}
I możesz to zrobić. Klasa główna jest klasą zagnieżdżoną

Wywoływanie zwykłych (niestatycznych) metod klasy z main()metody statycznej

„Czasami początkujący programiści próbują uzyskać dostęp do niestatycznych zmiennych i metod z metody main()lub innych metod statycznych. Taki kod oczywiście nie zadziała.

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

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

mainMetoda może odnosić się tylko do metod/zmiennych statycznych. Cóż, albo musi najpierw utworzyć instancję klasy Solution, a dopiero potem wywołać metody niestatyczne tego obiektu. Przykład:

Rozwiązanie 1 Rozwiązanie 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();
  }
}

Deklarowanie konstruktora jako metody

„Kolejnym częstym błędem jest niepoprawne zadeklarowanie konstruktora klasy. Nazwa konstruktora musi być taka sama jak nazwa klasy, a konstruktor nie ma typu wyniku. Najczęstsze błędy wyglądają tak:

public class Person
{
   private String value;

   void Person(String value)
   {
      this.value = value;
   }
}
Nie powinno tu być typu zwracanego
public class Person
{
   private String value;

   constructor(String value)
   {
      this.value = value;
   }
}
Nazwa konstruktora jest nieprawidłowa. Musi pasować do nazwy klasy
public class Person
{
   private String value;

   Person(String value)
   {
      value = value;
   }
}
this brakuje. Zmienna valuezostanie przypisana do siebie
public class Person
{
   private String value;

   Person(String value)
   {
      this.value = value;
   }
}
To wszystko jest poprawne.

Niepoprawne dziedziczenie interfejsów

„Twórcy Javy starali się, aby była ona bardzo zbliżona do języka angielskiego, więc wybrali inne słowa kluczowe dla pewnych powiązanych pojęć.

Kiedy klasa dziedziczy klasę, musisz użyć słowa extendskluczowego:

class Pet
{
}

class Cat extends Pet
{
}

„Kiedy klasa dziedziczy interfejs, a dokładniej go implementuje, musisz użyć słowa implementskluczowego:

interface Meow
{
}

class Cat implements Meow
{
}

„Kiedy interfejs dziedziczy interfejs, użyj słowa extendskluczowego:

interface Meow
{
}

interface Voice extends Meov
{
}

Pominięcie breakw switchoświadczeniu

„Ostatnim błędem na dziś, ale nie ostatnim dla początkujących, jest nieumieszczenie stwierdzenia breakw switchoświadczeniu. Przykład:

Zło Prawidłowy
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;
}

„Wiesz, Diego… Sądząc po zestawie błędów, które tu przedstawiłeś, wydaje mi się, jakbyś czytał mój osobisty dziennik… Albo obserwował, jak rozwiązuję zadania”.

„Ha! Nie mam co do tego wątpliwości. Czytałem, śledziłem i nadal to robię. Więc bądź czujny!”

"???"

„Nie martw się. Żartuję. Bądź czujny i popełniaj mniej głupich błędów”.