Вы — начинающий Java-разработчик в IT-компании. Вам поступило пять «дел» — реальных проблем, с которыми сталкиваются программисты. В каждом деле есть код с ошибкой или непонятное поведение. Ваша задача — диагностировать проблему и предложить решение.
Коллега просит помочь: у него есть класс StudentGroup, который хранит студентов в ArrayList. Метод getStudents() возвращает этот список наружу. Приложение работает, но иногда студенты «исчезают» или появляются «лишние». Код:
Ваша задача:
group.getStudents().clear(). А если кто-то добавит «чужого» студента? Это нарушает инкапсуляцию. Два варианта решения:return new ArrayList<>(students) — снаружи можно менять, но оригинал не тронется.return Collections.unmodifiableList(students) — снаружи менять нельзя вовсе, но изменения в оригинале видны через обёртку.Разработчик сделал окно Swing с кнопкой «Сохранить». При нажатии ничего не происходит. Код:
Ваша задача: найдите ошибку и объясните, что нужно добавить, чтобы окно появилось и кнопка работала.
panel и с frame. Панель не добавлена в окно, а окно не показано. Нужны строки frame.add(panel) и frame.setVisible(true).
В игре «Поймай кота» счётчик очков увеличивается сразу на 2 при одном клике. Код:
Ваша задача: объясните, почему счётчик растёт дважды, и как это исправить.
ActionListener и MouseListener. При клике срабатывают оба: JButton генерирует ActionEvent (его ловит первый) и MouseEvent (его ловит второй). Значит, score++ выполняется дважды. Решение: оставить один слушатель — обычно ActionListener. События мыши на кнопке нужны редко (например, для правой кнопки или перетаскивания).
В JavaFX-приложении разработчик связал метку с полем ввода, но при вводе текста метка не меняется. Код:
Ваша задача: объясните, почему метка не обновляется, и как это исправить.
root.getChildren().add(nameLabel) нигде не вызывается. Биндинг есть, значение в модели меняется, но метки на экране нет. Ещё одна возможная причина в похожих ситуациях — изменение свойства не в FX Application Thread (например, из new Thread(...)): JavaFX не обновит UI из чужого потока.
Проект собирается, но при запуске падает с ошибкой:
В коде вызывается StringUtils.reverse("hello"). Класс StringUtils лежит в отдельном JAR-файле utils-1.0.jar, который подключён к проекту. Разработчик уверен, что метод есть.
Ваша задача: объясните, почему возникает эта ошибка, и как её исправить.
NoSuchMethodError — ошибка во время выполнения, а не компиляции. Значит, компилятор видел метод, а JVM — нет. Это классическая проблема несовпадения версий: в проекте два JAR-файла с одинаковым классом, и загружается «старый», где метода нет. Решение: проверить classpath, убедиться, что используется одна версия JAR, пересобрать проект.
В реальной работе не бывает так, чтобы всё получалось с первого раза. Умение описать проблему — такой же навык, как умение писать код. Если вы застряли — не молчите и не бросайте задание.
Помните: «не получилось, но я понял, где именно» — это нормальный результат практики. Хуже — когда непонятно, что именно не получилось.
Одно и то же можно решить по-разному. Чем больше способов вы попробуете — тем лучше поймёте тему. Вот идеи для каждого дела:
List.copyOf(students) (неизменяемая копия, Java 10+). Или сделать поле final и вернуть только количество: getCount(). Или дать клиенту методы add/remove, а список не показывать вовсе.
№ 2
Можно добавить панель не в frame, а в frame.getContentPane(). Можно задать frame.setLocationRelativeTo(null) для центрирования. Можно сделать окно через JOptionPane.showMessageDialog() — без JFrame вообще.
№ 3
Можно оставить только MouseListener — если нужна реакция именно на мышь. Или добавить проверку e.getButton() == MouseEvent.BUTTON1, чтобы правая кнопка не считалась. Или разделить score++ на два счётчика — «клик кнопкой» и «клик мышью».
№ 4
Можно заменить bind() на bindBidirectional() — если метка должна ещё и влиять на модель. Можно добавить nameLabel.textProperty().addListener(...) для отладки: печатать в консоль, когда свойство меняется.
№ 5
Можно проверить classpath командой java -cp ... MyApp с явным указанием JAR. Можно собрать проект через javac -d out src/**/*.java и запустить через java -cp out:lib/utils-2.0.jar MyApp. Можно использовать jdeps — утилиту JDK для анализа зависимостей.
Вы прошли все пять дел. Теперь составьте краткий итог: какие ошибки вы нашли, какие приёмы использовали и что нового узнали.