1. Porównywanie obiektów z==

Ulubionym błędem początkujących programistów jest porównywanie obiektów (zwłaszcza łańcuchów znaków) za pomocą ==operatora. Na 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");
}

Ten kod nigdy nie wyświetli komunikatu „Ciągi są równe”, ponieważ ifinstrukcja porównuje odwołania do dwóch różnych obiektów ciągów.

Oto poprawna wersja kodu:

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


2. Zmiana Stringobiektu

Początkujący programiści często zapominają, że wszystkie obiekty klasy są niezmienne i że każda metoda tej Stringklasy zwraca nowy obiekt — bieżący obiekt nigdy się nie zmienia.

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


3. Zapominanie o inicjalizacji obiektów będących elementami tablicy

Innym częstym błędem jest zapomnienie 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.

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


4. Używanie zmiennej lokalnej zamiast zmiennej instancji.

Nowicjusze nie lubią wymyślać długich i znaczących nazw zmiennych. Często używają jednoliterowych nazw: a, b, i, itd. 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;
    }
  }
}

Powyższy kod nie skompiluje się. 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 < count; i++)
      {
         a[i] = value;
      }
   }
}


5. Usuwanie elementu kolekcji

Bardzo często zdarzają się sytuacje, kiedy jakiś element trzeba usunąć z kolekcji. Kod wygląda mniej więcej tak:

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


6. Umieszczenie kilku klas z publicmodyfikatorem w jednym pliku

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

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ą


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

Główna metoda może odnosić się tylko do metod/zmiennych statycznych. Cóż, albo musi najpierw stworzyć 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();
  }
}


8. Deklaracja konstruktora jako metody

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




Nieprawidłowa nazwa konstruktora. Nazwa konstruktora musi być zgodna z nazwą 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


9. 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 niektórych powiązanych pojęć.

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

class Pet
{
}

class Cat extends Pet
{
}

Kiedy klasa dziedziczy interfejs, musisz użyć słowa implementskluczowego:

interface Meow
{
}

class Cat implements Meow
{
}

Gdy interfejs dziedziczy interfejs, użyj extendssłowa kluczowego:

interface Meow
{
}

interface Voice extends Meow
{
}


10. Pominięcie breakw switchoświadczeniu

Ostatnim błędem popełnianym przez nas dzisiaj, ale nie ostatnim dla początkujących, jest nieumieszczenie oświadczenia 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;
}