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("Рядки однакові");
}

12
Задача
Java Syntax Zero,  12 рівень6 лекція
Недоступна
Яблука бувають різними
Виправ помилку в коді, щоб програма виводила на екран фразу "телефони однакові".

2. Змінення об'єкта String

Часто програмісти-новачки забувають, що всі об'єкти класу є незмінними (immutable) й усі методи класу String повертають новий об'єкт, а поточний об'єкт ніколи не змінюється.

Приклад:

String s = "Привіт";
s.toUpperCase(); // перетворення рядка у верхній регістр

Такий код дуже схожий на правильний, але він не працюватиме. Метод toUpperCase() не змінює об'єкт, для якого його викликано. Правильний код матиме такий вигляд:

String s = "Привіт";
String result = s.toUpperCase(); // перетворення рядка у верхній регістр

12
Задача
Java Syntax Zero,  12 рівень6 лекція
Недоступна
Усі літери малі
Програма має зчитати з консолі рядок і вивести його на екран у нижньому регістрі. Виправ помилку в коді, щоб програма компілювалася й працювала.

3. Не ініціалізовано об'єкти, які є елементами масиву

Ще одна поширена помилка програмістів-початківців — вони забувають ініціалізувати змінну-масив. Приклад:

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

Такий код не працюватиме: змінній array потрібно явно присвоїти посилання на об'єкт-контейнер, який буде зберігати елементи масиву.

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

12
Задача
Java Syntax Zero,  12 рівень6 лекція
Недоступна
Забута ініціалізація
У програмі масив заповнюється числами від 0 до 9, і його вміст виводиться на екран. Однак через помилку програма не компілюється. Зроби так, щоб програма компілювалася й правильно працювала.

4. Підміна поля класу локальною змінною

Новачки не люблять придумувати довгі й осмислені імена для змінних. Вони часто дають змінним імена a, b, i тощо. Це може обернутися суттєвими помилками в коді, коли таких змінних декілька:

Записати число 99 у 100 комірок масиву
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;
    }
  }
}

Наведений вище код не скомпілюється. Виправлений код матиме такий вигляд:

Записати число 99 у 100 комірок масиву
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;
      }
   }
}

12
Задача
Java Syntax Zero,  12 рівень6 лекція
Недоступна
Затінення поля класу
Метод main містить виклик методу add, який має збільшувати значення поля salary класу Solution на передане значення, але значення поля salary, яке виводиться на екран, — 0. Зроби так, щоб програма працювала правильно.

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

По-друге, починаючи з Java 8 у колекцій з'явився метод remove If(), в який можна передати правило (лямбда-функцію), що вказує, які елементи потрібно видалити.

Приклад:

Варіант 2
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 0, -5, -7, -12, 5, 15);

list.removeIf( x-> x<0 );

12
Задача
Java Syntax Zero,  12 рівень6 лекція
Недоступна
Відчуй себе деканом
Маємо групу в університеті й метод, який має відраховувати конкретного студента, але чомусь цей метод не працює. Твоє завдання — знайти й виправити помилку, щоб метод exclude таки зміг відрахувати студента.

6. Розміщення в одному файлі декількох класів із модифікатором public

Кожен файл може містити тільки один публічний клас. Файл може містити оголошення й інших класів, але вони мають бути або внутрішніми класами публічного класу, або ж не повинні мати модифікатора public. Приклад:

Вміст файлу Solution.java Примітка
public class Solution
{
}
public class Main
{
}
Так не можна: два публічні класи в одному файлі.
public class Solution
{
}
class Main
{
}
А так можна. Клас Main — непублічний
public class Solution
{
  public static class Main
  {
  }
}
Так теж можна. Клас Main — вкладений клас

12
Задача
Java Syntax Zero,  12 рівень6 лекція
Недоступна
MacCoffee 3 в 1
У нас є набір класів для того, щоб зробити каву три-в-одному, але кава чомусь не заварюється — задача не компілюється. Знайди та виправ у коді одну помилку.

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

12
Задача
Java Syntax Zero,  12 рівень6 лекція
Недоступна
Складаємо список студентів
Метод main має додавати двох студентів у масив і виводити їхні імена в консоль за допомогою методу printStudents. Зроби виправлення в методі main, щоб програма запрацювала.

8. Оголошення конструктора як методу

Ще одна поширена помилка — неправильне оголошення конструктора класу. Ім'я конструктора має збігатися з іменем класу, а типу результату конструктор не має. Приклади найчастіших помилок:

public class Person
{
   private String value;

   void Person(String value)
   {
      this.value = value;
   }
}




Тип результату тут не потрібен
public class Person
{
   private String value;

   constructor(String value)
   {
      this.value = value;
   }
}




Неправильне ім'я конструктора. Ім'я конструктора має збігатися з іменем класу
public class Person
{
   private String value;

   Person(String value)
   {
      value = value;
   }
}






Пропущено this — змінну value буде присвоєно самій собі
public class Person
{
   private String value;

   Person(String value)
   {
      this.value = value;
   }
}




Усе правильно

12
Задача
Java Syntax Zero,  12 рівень6 лекція
Недоступна
Студент
Метод main класу Solution створює об'єкт класу Student із певним іменем, але програма не компілюється. Ти маєш виправити помилку в класі Student, щоб програма компілювалася та після запуску виводила в консоль ім'я студента.

9. Неправильне успадкування інтерфейсів

Розробники Java намагалися зробити її якомога ближчою до англійської мови, тому для деяких споріднених понять вони вибрали різні ключові слова.

Коли клас успадковується від класу, потрібно використовувати ключове слово extends:

class Pet
{
}

class Cat extends Pet
{
}

Коли клас успадковується від інтерфейсу, потрібно використовувати ключове слово implements:

interface Meow
{
}

class Cat implements Meow
{
}

Коли інтерфейс успадковується від інтерфейсу, потрібно використовувати ключове слово extends:

interface Meow
{
}

interface Voice extends Meow
{
}

12
Задача
Java Syntax Zero,  12 рівень6 лекція
Недоступна
Телефон у спадок
Потрібно правильно розмістити ключові слова extends і implements у наявних класах, щоб програма компілювалася.

10. Пропуск слова break в операторі switch

І остання помилка в нашому переліку, але не остання для новачків — це пропуск оператора break в операторі множинного вибору switch. Приклад

Неправильно Правильно
LocalDate date = LocalDate.now();
DayOfWeek day = date.getDayOfWeek();
switch (day)
{
   case MONDAY:
      System.out.println("Понеділок");
   case TUESDAY:
      System.out.println("Вівторок");
   case WEDNESDAY:
      System.out.println("Середа");
   case THURSDAY:
      System.out.println("Четвер");
   case FRIDAY:
      System.out.println("П'ятниця");
   case SATURDAY:
      System.out.println("Субота");
   case SUNDAY:
      System.out.println("Неділя");
}
LocalDate date = LocalDate.now();
DayOfWeek day = date.getDayOfWeek();
switch (day)
{
   case MONDAY:
      System.out.println("Понеділок");
      break;
   case TUESDAY:
      System.out.println("Вівторок");
      break;
   case WEDNESDAY:
      System.out.println("Середа");
      break;
   case THURSDAY:
      System.out.println("Четвер");
      break;
   case FRIDAY:
      System.out.println("П'ятниця");
      break;
   case SATURDAY:
      System.out.println("Субота");
      break;
   case SUNDAY:
      System.out.println("Неділя");
      break;
}

12
Задача
Java Syntax Zero,  12 рівень6 лекція
Недоступна
Текстові цифри
Програма перетворює цифри на текст. Клас Solution містить статичний метод digitToText(char), який повертає цифри у вигляді тексту. Метод main перетворює число на текст, але на екран виводиться тільки "дев'ять дев'ять ... ". Додай у метод digitToText(char) потрібну кількість операторів break, щоб він