Najczęstsze błędy początkujących programistów

początkujący programista

Wszyscy popełniamy błędy, natomiast programiści mają ku temu znacznie więcej okazji. W dzisiejszym artykule przyjrzymy się błędom, które są najczęściej popełniane przez początkujących programistów Java. Na naszych kursach (m.in. Tester Automatyzujący) uczymy jak się przed nimi ustrzec.

1. Porównywanie obiektów za pomocą operatora „==”.

Ten punkt nie powinien być chyba dla nikogo zaskoczeniem. Operator porównania może być bezpiecznie stosowany do porównywania typów prostych. W przypadku obiektów może nastręczyć wiele problemów (pod warunkiem, że naszym celem nie jest porównanie referencji). Jeśli porównywane w ten sposób obiekty znajdują się w innym miejscu w pamięci, użycie operatora porównania zawsze zwróci false, nawet jeśli porównywane obiekty są identyczne.

Cat cat1 = new Cat("Tom", 5);
Cat cat2 = new Cat("Tom", 5);

System.out.println(cat1 == cat2); //false

Jak zatem upewnić się, czy dwa obiekty są równe? Służy do tego metoda equals(). Każda klasa posiada jej domyślną implementację odziedziczoną po klasie Object. Oczywiście, aby prawidłowo porównywać nasze obiekty, należy nadpisać tę metodę uwzględniając prawidłowe kryteria porównywania.

String s1 = "Some text";
String s2 = new String("Some text");

System.out.println(s1.equals(s2)); //true

2. Brak zrozumienia w jaki sposób działa klasa String.

Klasa String jest jedną z najczęściej wykorzystywanych.. Początkujący programiści często zapominają, że klasa String jest typu immutable. Nie ma możliwości edycji raz zdefiniowanej zmiennej tego typu. Oznacza to, iż każda edycja wartości zmiennej typu String wiąże się ze zmianą referencji, a nie z faktyczną jej edycją w pamięci. W takiej sytuacji program javowy będzie najpierw szukał nowego Stringa w tzw. String pool, a w przypadku jego braku, stworzy nowy String.

Na poniższym przykładzie oba obiekty wskazują na to samo miejsce w pamięci (w String pool), w związku z czym operacja porównania za pomocą operatora „==” zwróci true

String s1 = "Some text";
String s2 = "Some text";

System.out.println(s1 == s2); //true

3. Brak zrozumienia w jaki sposób argumenty przekazywane są do metod (przez wartość lub referencję).

Typy proste oraz obiekty są przekazywane do metod jako parametry na dwa różne sposoby. Typy proste – przez wartość, obiekty – przez referencję. Oznacza to, że przekazując do metody typ prosty, jeśli wartość przekazana do metody ulegnie zmianie wewnątrz tej metody, wartość przekazanej zmiennej nie zostanie zmieniona.

Przyjrzyjmy się poniższemu przykładowi. W metodzie main() wywołane zostały dwie metody:

  • podzielNaDwa(n) – do tej metody przekazaliśmy zmienną typu prostego o nazwie n
  • zaktualizujWiek(czlowiek) – do tej z kolei przekazaliśmy obiekt typu Czlowiek o nazwie czlowiek
public class Test {
    public static void main(String[] args) {

        int n = 10;
        Czlowiek czlowiek = new Czlowiek(25);

        podzielNaDwa(n);
        System.out.println(n); //10

        zaktualizujWiek(czlowiek);
        System.out.println(czlowiek.getWiek()); //26

    }

    public static void podzielNaDwa(int n){
        n = n / 2;
    }

    public static void zaktualizujWiek(Czlowiek czlowiek){
        czlowiek.setWiek(czlowiek.getWiek() + 1);
    }
}

Pierwsza metoda dzieli przekazaną wartość na 2. Po jej wywołaniu i wyświetleniu zmiennej n okazuje się, że nie została ona zmieniona i nadal wynosi 10. Dzieje się tak dlatego, bo do metody przekazaliśmy wartość zmiennej, a nie ją samą.

Inaczej sprawa się ma w przypadku obiektu czlowiek przekazanego do metody zaktualizujWiek(). Metoda ta inkrementuje atrybut wiek o 1. Po jej wywołaniu i wyświetleniu wartości atrybutu okazuje się, że został on zmieniony. Powodem jest fakt, iż do metody przekazaliśmy obiekt, a konkretniej – referencję wskazującą na miejsce w pamięci, wobec czego wszelkie operacje na obiekcie dotyczą właśnie tego przekazanego do metody.

4. Niestosowanie się do ogólnych zasad programowania.

Programiści bardzo sporadycznie piszą kod dla siebie. Zdecydowanie częściej w pewnym momencie ich kod otrzyma „w spadku” inny programista. Poza zasadami typowo technicznymi, dla poprawy czytelności kodu stosuje się ogólne zasady nazewnictwa klas, metod, zmiennych i stałych.

int number;
Czlowiek czlowiek;
boolean czyWciazZyje;
final double DRUGA_PREDKOSC_KOSMICZNA = 11.19;