— Привет, Амиго. Продолжаем говорить об ошибках. На этот раз те, с которыми компилятор тебе поможет далеко не всегда. Слушай и узнавай себя.

— Готов внимать, Диего. Надеюсь, мне будет не очень стыдно.

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

— Наш топчик любимых ошибок программистов-новичков открывает “сравнение объектов (особенно строк) с помощью оператора ==

Пример:

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("Строки равны");
}
undefined
11
Задача
Java Syntax Pro, 11 уровень, 6 лекция
Недоступна
Дефрагментация памяти
Рассмотрим аналог памяти компьютера на примере массива строк. Если удалить некоторые элементы, то в массиве появятся так называемые "дыры" - то есть элементы равные null. Метод executeDefragmentation(String[]), принимающий массив строк, выполняет его "дефрагментацию", то есть

Изменение объекта String

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

— Я не так давно выучил про immutable, но, кажись, было дело.

— Я почти уверен, что было. Пример:

String s = "Привет";
s.toUpperCase(); //преобразование строки к верхнему регистру

— Такой код очень похож на правильный, но работать не будет. Метод toUpperCase() не меняет объект, у которого был вызван. Правильный код будет выглядеть так:

String s = "Привет";
String result = s.toUpperCase(); //преобразование строки к верхнему регистру

— Точно. Я так делал, но даже толком не понимал, что не так. Спасибо за пояснение!

undefined
11
Задача
Java Syntax Pro, 11 уровень, 6 лекция
Недоступна
Расставь правильно этажи
Сейчас мы видим, что класс Hotel не компилируется. Нужно расставить поля класса в таком порядке, что бы он скомпилировался.

Забыли проинициализировать объекты, являющиеся элементами массива

— Еще одна частая ошибка — забыли инициализировать переменную-массив. Пример:

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

— Такой код работать не будет: в переменную array нужно явно присвоить ссылку на объект-контейнер, который будет хранить элементы массива. Правильный вариант:

int[] array = new int[10];
array[0] = 1;
array[0] = 2;
undefined
11
Задача
Java Syntax Pro, 11 уровень, 6 лекция
Недоступна
Купи 10 батонов
Тебя отправили в магазин за покупками и сказали, что нужно купить батон, а если будут яйца, то взять десять штук. Разберись, почему метод makePurchases независимо от переданных аргументов всегда выводит в консоль "Купил 10 батонов", и исправь его. Метод main не участвует в проверке.

Подмена поля класса локальной переменной.

—Новички не любят придумывать длинные и осмысленные названия переменным.

— Так и есть. Я иногда для скорости называю переменные a, b, i и так далее.

— Не делай так. Это может сыграть злую шутку, когда таких переменных в коде несколько:

Занести в 100 ячеек массива число 99
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;
    }
  }
}

— Гораздо сложнее ошибиться в коде с нормальными названиями. Исправленный вариант будет выглядеть так:

Занести в 100 ячеек массива число 99
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;
      }
   }
}
undefined
11
Задача
Java Syntax Pro, 11 уровень, 6 лекция
Недоступна
Ежик и яблоко
Наша задача — накормить ежика. Нужно в методе main создать один объект Apple и один объект Hedgehog, у которого вызвать метод eat и передать нужный аргумент — яблоко.

Удаление элемента коллекции

— Ты уже заглядывал в коллекции?

— Буквально одним глазком.

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

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, появился метод removeIf(), в который можно передать правило (лямбда-функцию), указывающее, какие элементы нужно удалить. Пример:

Решение 2
ArrayList<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, 0, -5, -7, -12, 5, 15);

list.removeIf( x-> x<0 );
undefined
11
Задача
Java Syntax Pro, 11 уровень, 6 лекция
Недоступна
Прогноз погоды
У класса City есть два поля - название города и текущая температура воздуха. Также в классе Solution есть метод showWeather: он выводит в консоли информацию о погоде в городе, который передан в качестве аргумента метода. Реализуй метод showWeather, который должен выводить в консоли информацию в таком

Помещение в один файл сразу нескольких классов с модификатором public

— В одном файле может быть только один публичный класс. В файле могут быть объявлены еще классы, но они должны быть или внутренними классами публичного класса, или же не иметь модификатора public. Пример:

Содержимое файла Solution.java Примечание
public class Solution
{
}
public class Main
{
}
Так нельзя: два публичных класса в одном файле.
public class Solution
{
}
class Main
{
}
А так можно. Класс Main — не публичный
public class Solution
{
  public static class Main
  {
  }
}
И так можно. Класс Main — вложенный класс
undefined
11
Задача
Java Syntax Pro, 11 уровень, 6 лекция
Недоступна
Создание материков
Как известно, на планете Земля есть 6 материков. Создай для каждого материка собственный класс. В каждом классе должно быть поле, которое хранит площадь соответствующего материка. Площадь материка нужно указывать при его создании, и она должна быть неизменяемой. Ты можешь использовать любые числа д

Вызов обычных методов класса из метода статического 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();
  }
}
undefined
11
Задача
Java Syntax Pro, 11 уровень, 6 лекция
Недоступна
Геттер и сеттер в деле
В классе Coordinate есть 2 геттера и 2 сеттера, но значения переменным сеттеры не устанавливают. Разберись, почему так происходит и исправь. Метод main не участвует в проверке.

Объявление конструктора как метода

— Ещё одна частая ошибка — неверное объявление конструктора класса. Имя конструктора должно совпадать с именем класса, и типа-результата у конструктора нет. Самые частые ошибки выглядят так:

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;
   }
}
Все правильно.
undefined
11
Задача
Java Syntax Pro, 11 уровень, 6 лекция
Недоступна
Текущий год
В классе Solution есть поле currentYear, которое должно инициализироваться значением текущего года(Calendar.getInstance().get(Calendar.YEAR)) при создании нового объекта типа Solution. Тебе нужно найти ошибку и исправить её, чтобы при создании объекта класса Solution поле currentYear правильно иниц

Неверное наследование интерфейсов

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

Когда класс наследуется от класса, нужно использовать ключевое слово extends:

class Pet
{
}

 class Cat extends Pet
 {
 }

— Когда класс наследуется от интерфейса, а, точнее — реализует его, нужно использовать ключевое слово implements:

interface Meow
{
}

 class Cat implements Meow
 {
 }

— Когда интерфейс наследуется от интерфейса, нужно использовать ключевое слово extends:

interface Meow
{
}

interface Voice extends Meov
{
}
undefined
11
Задача
Java Syntax Pro, 11 уровень, 6 лекция
Недоступна
Собираем компьютер
Попробуем собрать компьютер. У нас есть классы: системный блок, монитор, клавиатура, мышь. В классе компьютер в конструкторе создай объекты классов-составляющих компьютера.

Пропуск слова 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;
}

— Да, Диего… Судя по коллекции ошибок, такое ощущение, что ты прямо читал мой дневник… Или следил за тем, как я решаю задачки.

— Ха! Даже не сомневайся. И читал, и следил, и продолжаю. Так что будь на чеку!

— ???

— Не дрейфь, шучу. Будь на чеку и делай поменьше глупых ошибок.

undefined
11
Задача
Java Syntax Pro, 11 уровень, 6 лекция
Недоступна
Автопроизводитель
Давай создадим каталог новых моделей авто у нас на производстве. Для этого нам нужно создать один метод initialize, который будет инициализировать такие поля объекта типа Car: модель, год выпуска, цвет.