8 типичных ошибок начинающих Java-разработчиков

🔥 🚀 Важно для всех, кто работает с Java! 🔥
На JavaRocks ты найдешь уникальные туториалы, практические задачи и редкие книги, которых не найти в свободном доступе. Присоединяйся к нашему Telegram-каналу JavaRocks — стань частью профессионального сообщества!

В этой статье разберём 8 самых распространенных ошибок, которые допускают начинающие (и не только) Java-разработчики. В сети можно найти множество подобных списков — многие из них довольно похожи между собой.

Список не отсортирован по важности — они все одинаково важны для понимания и их стоит запомнить.

Ошибка 1. Сравнение объектов с помощью ==

Оператор == сравнивает ссылки на объекты, а не их содержимое.

Ссылки указывают на адреса в памяти. Если два объекта находятся по разным адресам, то сравнение с помощью == вернет false.

public class Vehicle {

    String model;
    int maxSpeed;
    int yearOfManufacture;

    public Car(String model, int maxSpeed, int yearOfManufacture) {
        this.model = model;
        this.maxSpeed = maxSpeed;
        this.yearOfManufacture = yearOfManufacture;
    }

    public static void main(String[] args) {
        Car ferrari = new Car("Ferrari 360 Spider", 280, 1996);
        Car ferrariTwin = new Car("Ferrari 360 Spider", 280, 1996);
        System.out.println(ferrari == ferrariTwin);
    }
}
Run Code

Для сравнения объектов в классе Object есть специальный метод: equals(). Если честно, его стандартная реализация неплоха:

public boolean equals(Object obj) {
    return (this == obj);
}
Run Code

В самом классе Object метод equals() реализован как сравнение двух ссылок. Чтобы корректно сравнивать объекты, необходимо переопределить этот метод с учетом критериев равенства, которые актуальны в конкретной программе для конкретных объектов. Какие именно это будут критерии — вы решаете сами.

Единственное, о чем нельзя забывать, — это список требований для правильного переопределения equals(). Их легко можно найти в Интернете.

Ошибка 2. Использование нестатических переменных в статических методах (и наоборот)

Если вы когда-нибудь видели сообщение “Non-static variable x cannot be referenced from a static context”, добро пожаловать в клуб 🙂

У статических методов нет доступа к нестатическим (экземплярным) переменным.

Это логично: статический метод можно вызвать без создания объекта класса, а нестатические поля принадлежат конкретным объектам. Именно в этом и заключается противоречие, которое приводит к ошибке.

А в обратную сторону всё работает нормально: в нестатических методах можно спокойно обращаться к статическим переменным.

public class Main {

    public int x = 10;

    public static int staticX = 100;

    public static void main(String[] args) {

        System.out.println(x); // Compilation error - you can't do this!
    }

    public void printX() {

        System.out.println(staticX); // But you can do this!
    }
}
Run Code

Ошибка 3. Непонимание механизма передачи аргументов в методы: по ссылке или по значению

В Java объекты и примитивы передаются в методы по-разному: первые — по ссылке, вторые — по значению.

Для новичков этот момент часто оказывается сложным для понимания. В результате код ведет себя не так, как ожидалось:

public class Main {

    public static void main(String[] args) {

        int x = 7;
        incrementNumber(x);
        System.out.println(x);

        Cat cat = new Cat(7);
        catLevelUp(cat);
        System.out.println(cat.getAge());

    }

    public static void catLevelUp(Cat cat) {

        cat.setAge(cat.getAge()+1);
    }

    public static void incrementNumber(int x) {
        x++;
    }
}
Run Code

Если вы не знаете, какое именно число будет увеличиваться, а какое нет (простое число или возраст кошки), то прочитайте эту статью.

Ошибка 4. Игнорирование правил кодирования

Это относится не только к соблюдению определенных “технических” принципов, но и к обычным соглашениям о наименованиях.

Все эти правила (как называть переменные, как писать имена методов) придуманы не просто так. Они действительно влияют на читаемость кода.

В конце концов, код — не всегда будет принадлежать только вам. Вас могут перевести на другой проект внутри компании, а коллегам, которые унаследуют ваш код, вряд ли будет приятно увидеть нечто подобное:

public class Cat {

    private int S_O_M_E_T_H_I_N_G = 7;
    public String striiiiiiiiiiiiiing;
    protected double I_HAVE_NO_IDEA_WHAT_THIS_IS = 3.14;
    boolean random = Math.random() > 0.5;

}
Run Code

Даже если ваш код суперэффективный, но невозможно прочитать и понять, как он работает, то, увы, толку от него немного.

Если вы придерживаетесь стандартов кодирования, то даже неидеальный код будет понятен более опытным коллегам. А значит, они смогут подсказать, как его улучшить 🙂

Ошибка 5. Непонимание класса String

public class Main {

    public static void main(String[] args) {

        String s1 = "I'm learning Java";
        String s2 = new String("I'm learning Java");

        System.out.println(s1 == s2);
    }
}
Run Code

Если вы не понимаете, почему этот код выводит false, то вам явно нужно подтянуть теорию 🙂

Новички часто не знают о существовании String Pool и принципах его работы. В результате они не совсем понимают, как правильно сравнивать строки в своем коде.

Ошибка 6. Неправильная обработка исключений

С этой проблемой сталкиваются не только новички, но и опытные разработчики. Причин тому множество.

Во-первых, не существует универсального рецепта: ошибки бывают самые разные, и сценарии обработки — тоже.

Во-вторых, не все до конца понимают, как устроен стек вызовов (stack trace). Существует множество антипаттернов обработки ошибок, и каждый из них по-своему “неправильный”. Это значит, что ошибиться в обработке ошибок гораздо проще, чем кажется.

Ошибка 7. Непонимание механики операторов в Java: арифметических, логических и т.д.

Операторы Java

Вот простой пример. Можете сразу сказать, что выведет этот код?

public class Main {

    public static void main(String[] args) {

        int i = 6;
        System.out.println(7 == i++);
    }
}
Run Code

Если вы ответили неправильно или просто угадали, значит, вам следует подтянуть свои знания 🙂

Код выведет false. Сначала выполняется сравнение 7 == i, а уже потом выполняется операция i++.

На эту тему вы можете почитать эту статью.

Ошибка 8. Пропущенный break в конструкции switch

Наверняка почти каждый, кто работает с Java, совершал эту ошибку 🙂

public class Main {

    public static void main(String[] args) {

        int i = 1;

        switch (i) {

            case 1: {
                System.out.println("The number is equal to 1");
            }
            case 2: {
                System.out.println("The number is equal to 2");
            }
            case 3: {
                System.out.println("The number is equal to 3");
            }
        }
    }
 }
Run Code

В результате выполнение перебирает все возможные варианты.

Вывод:

The number is equal to 1
The number is equal to 2
The number is equal to 3

Оператор break прерывает выполнение конструкции switch, как только нужный блок завершен. Если забыть его — можно получить совсем не то, что ожидалось 🙂

Перевод статьи «8 common mistakes made by rookie programmers».

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх