1. Сравнение объектов с помощью ==
Любимая ошибка программистов-новичков — сравнение объектов (особенно строк) с помощью оператора ==
Пример:
Scanner console = new Scanner(System.in);
String s1 = console.nextLine();
String s2 = console.nextLine();
if (s1 == s2)
{
System.out.println("Строки равны");
}
Такой код никогда не выведет надпись «строки равны», т.к. в if
-е происходит сравнение ссылок на два разных объекта строк.
Правильный вариант кода такой:
Scanner console = new Scanner(System.in);
String s1 = console.nextLine();
String s2 = console.nextLine();
if (s1.equals(s2))
{
System.out.println("Строки равны");
}
2. Изменение объекта String
Часто программисты-новички забывают, что все объекты класса являются неизменяемыми (immutable), и все методы класса String
возвращают новый объект, а текущий объект никогда не меняется.
Пример:
String s = "Привет";
s.toUpperCase(); // преобразование строки к верхнему регистру
Такой код очень похож на правильный, но работать не будет. Метод toUpperCase()
не меняет объект, у которого был вызван. Правильный код будет выглядеть так:
String s = "Привет";
String result = s.toUpperCase(); // преобразование строки к верхнему регистру
3. Забыли проинициализировать объекты, являющиеся элементами массива
Еще одна частая ошибка — забыли инициализировать переменную-массив. Пример:
int[] array;
array[0] = 1;
array[0] = 2;
Такой код работать не будет: в переменную array нужно явно присвоить ссылку на объект-контейнер, который будет хранить элементы массива.
int[] array = new int[10];
array[0] = 1;
array[0] = 2;
4. Подмена поля класса локальной переменной.
Новички не любят придумывать длинные и осмысленные названия переменным. Часто у них переменные имеют имена a
, b
, i
и т.д. Это может сыграть злую шутку, когда таких переменных в коде несколько:
Занести в 100 ячеек массива число 99 |
---|
|
Код выше не скомпилируется. Исправленный вариант будет выглядеть так:
Занести в 100 ячеек массива число 99 |
---|
|
5. Удаление элемента коллекции
Очень часто бывают ситуации, когда из коллекции нужно удалить определенный элемент. Выглядит этот код примерно так:
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);
Такой код работать не будет, т.к. нельзя одновременно обходить элементы коллекции с помощью цикла for-each и изменять ту же самую коллекцию.
Есть несколько решений. Во-первых, можно идти по одной коллекции, а менять другую:
Решение 1 |
---|
|
Во-вторых, у коллекции, начиная с Java 8, появился метод removeIf()
, в который можно передать правило (лямбда-функцию), указывающее, какие элементы нужно удалить.
Пример:
Решение 2 |
---|
|
6. Помещение в один файл сразу нескольких классов с модификатором public
В одном файле может быть только один публичный класс. В файле могут быть объявлены еще классы, но они должны быть или внутренними классами публичного класса, или же не иметь модификатора public
. Пример:
Содержимое файла Solution.java | Примечание |
---|---|
|
Так нельзя: два публичных класса в одном файле. |
|
А так можно. Класс Main — не публичный |
|
И так можно. Класс Main — вложенный класс |
7. Вызов обычных методов класса из статического метода main()
Иногда программисты-новички обращаются к нестатическим переменным и методам из метода main()
или других статических методов. Такой код, конечно, не будет работать.
public class Solution
{
public int n = 100;
public int[] createArray()
{
return new int[n];
}
public static void main(String[]args)
{
int[] array = createArray();
}
}
Метод main может обратиться только к статическому методу/переменной. Ну или сначала создать объект класса Solution
, и только потом вызвать нестатические методы у этого объекта. Пример:
Решение 1 | Решение 2 |
---|---|
|
|
8. Объявление конструктора как метода
Еще одна частая ошибка — неверное объявление конструктора класса. Имя конструктора должно совпадать с именем класса, и типа-результата у конструктора нет. Самые частые ошибки выглядят так:
|
Тип результата тут не нужен |
|
Неверное имя конструктора. Имя конструктора должно совпадать с именем класса |
|
Пропущен this — переменная value будет присвоена сама себе |
|
Все правильно |
9. Неверное наследование интерфейсов
Разработчики Java старались сделать его очень близким к английскому языку, поэтому для некоторых родственных понятий они выбрали разные ключевые слова.
Когда класс наследуется от класса, нужно использовать ключевое слово extends
:
class Pet
{
}
class Cat extends Pet
{
}
Когда класс наследуется от интерфейса, нужно использовать ключевое слово implements
:
interface Meow
{
}
class Cat implements Meow
{
}
Когда интерфейс наследуется от интерфейса, нужно использовать ключевое слово extends
:
interface Meow
{
}
interface Voice extends Meow
{
}
10. Пропуск слова break
в операторе switch
И последняя у нас, но не последняя для новичков ошибка, — это пропуск оператора break
в операторе множественного выбора switch
. Пример
Неправильно | Правильно |
---|---|
|
|
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ