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
тощо. Це може обернутися суттєвими помилками в коді, коли таких змінних декілька:
Записати число 99 у 100 комірок масиву |
---|
|
Наведений вище код не скомпілюється. Виправлений код матиме такий вигляд:
Записати число 99 у 100 комірок масиву |
---|
|
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 у колекцій з'явився метод remove If()
, в який можна передати правило (лямбда-функцію), що вказує, які елементи потрібно видалити.
Приклад:
Варіант 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
. Приклад
Неправильно | Правильно |
---|---|
|
|