Как и какими средствами находить ошибки в коде Java?

233
03 августа 2017, 23:19

При написании кода он, порой, не работает так, как я задул или не работает в принципе. Я сижу и гадаю: что и где не так?

Немного посмотрев на код - иду на ресурсы профессионалов, например Stack Overflow и публикую вопрос "Где здесь ошибка?" или "Почему не работает?"

В итоге очень часто проблема мелкая: дурацкая опечатка, ошибка в синтаксисе и подобное. Профессионалом так не стать, если по каждой мелочёвке бегать по ресурсам. А я хочу им быть.

Вопрос: какие есть способы, чтобы найти ошибки в Java коде? Какие есть инструменты, методы, пути и пр.?

Answer 1

Вчера всё работало, а сегодня не работает / Код не работает как задумано

или

Debugging (Отладка)

В чем заключается процесс отладки? Что это такое?

Процесс отладки состоит в том, что мы останавливаем выполнения скрипта в любом месте, смотрим, что находится в переменных, в функциях, анализируем и переходим в другие места; ищем те места, где поведение отклоняется от правильного.

Будет рассмотрен пример с Intellij IDEA, но отладить код можно и в любой другой IDE.

Подготовка

Достаточно иметь в наличии IDE, например Intellij IDEA

Запуск

Для начала в левой части панели с кодом на любой строке можно кликнуть ЛКМ, тем самым поставив точку останова (breakpoint - брейкпойнт). Это то место, где отладчик автоматически остановит выполнение Java, как только до него дойдёт. Количество breakpoint'ов не ограничено. Можно ставить везде и много.

Отладка запускается сочетанием Shift+F9 или выбором в верхнем меню RunDebug или нажатием зеленого "жучка":

В данном случае, т.к. функция вызывается сразу на той же странице, то при нажатии кнопки Debug — отладчик моментально вызовет метод, выполнение "заморозится" на первом же брейкпойнте. В ином случае, для активации требуется исполнить действие, при котором произойдет исполнение нужного участка кода (клик на кнопку в UI, передача POST запроса с данными и прочие другие действия)

Цифрами обозначены:

  1. Стэк вызовов, все вложенные вызовы, которые привели к текущему месту кода.
  2. Переменные. На текущий момент строки ниже номера 24 ещё не выполнилась, поэтому определена лишь data и numsStringArr
  3. Показывает текущие значения любых переменных и выражений. В любой момент здесь можно нажать на +, вписать имя любой переменной и посмотреть её значение в реальном времени. Например data или nums[0], а можно и nums[i] и item.test.data.name[5].info[key[1]] и т.д. На текущий момент строки ниже номера 24 ещё не выполнилась, поэтому sum и output во вкладке Watchers обозначены красным цветом с надписью "cannot find local variable".

Процесс

Для самого процесса используются элементы управления (см. изображение выше, выделено зеленым прямоугольником) и немного из дополнительно (см. изображение выше, выделено оранжевым прямоугольником)

Show Execution Point (Alt+F10) — переносит в файл и текущую линию отлаживаемого скрипта. Например если файлов много, решили посмотреть что в других вкладках, а потом забыли где у вас отладка :)

Step Over (F8) — делает один шаг не заходя внутрь функции. Т.е. если на текущей линии есть какая-то функция, а не просто переменная со значением, то при клике данной кнопки, отладчик не будет заходить внутрь неё.

Step Into (F7) — делает шаг. Но в отличие от предыдущей, если есть вложенный вызов (например функция), то заходит внутрь неё.

Step Out (Shift+F8) — выполняет команды до завершения текущей функции. Удобна, если случайно вошли во вложенный вызов и нужно быстро из него выйти, не завершая при этом отладку.

Rerun (Ctrl+F5) — Перезапустить отладку

Resume Program(F9) — Продолжает выполнения скрипта с текущего момента. Если больше нет других точек останова, то отладка заканчивается и скрипт продолжает работу. В ином случае работа прерывается на следующей точке останова.

Stop (Ctrl+F2) — Завершить отладку

View Breakpoints (Ctrl+Shift+F8) — Посмотреть все установленные брейкпойнты

Mute Breakpoints — Отключить брейкпойнты.

...

Итак, в текущем коде видно значение входного параметра:

  • data = "23 24 11 18" — строка с данными через пробел
  • numsStringArr = {"23", "24", "11", "18"} — массив строк, который получился из входной переменной.

Если нажмем F8 2 раза, то окажемся на строке 27; во вкладках Watches и Variables и в самой странице с кодом увидим, что переменная sum была инициализирована и значение равно 0, а также nums инициализирована и в ней лежит массив целых чисел {23, 24, 11, 18} .

Если теперь нажмем F8, то попадем внутрь цикла for и нажимая теперь F8 пока не окончится цикл, можно будет наблюдать на каждой итерации, как значение num и sum постоянно изменяются. Тем самым мы можем проследить шаг за шагом весь процесс изменения любых переменных и значений на любом этапе, который интересует.

Дальнейшие нажатия F8 переместит линию кода на строки 31, 32 и, наконец, 36.

Дополнительно

Если нажать на View Breakpoints в левой панели, то можно не только посмотреть все брейкпойнты, но в появившемся окно можно еще более тонко настроить условие, при котором на данной отметке надо остановиться. В методе выше, например, нужно остановиться только когда sum превысит значение 20.

Это удобно, если останов нужен только при определённом значении, а не всегда (особенно в случае с циклами).

Больше информации об отладке можно посмотреть в http://learn.javajoy.net/debug-intellij-idea, а также в официальной документации к IDE

Answer 2
IDE!

Некоторые тонкости и особенности работы с Java можно освоить если писать код в блокноте и компилировать/запускать его через командные строки. Бесспорно. Но так уже никто не делает. Все давно пользуются IDE (Integrated Development Environment - Интегрированная среда разработки). Их очень много. Одна из популярных Intellij IDEA. Советую установить.

Они имеют много разных возможностей:

  • рефакторинг
  • детектор дублируемого кода
  • инструменты для работы с базами данных
  • интеграция с системами управления версиями
  • подсветка синтаксиса
  • автодополнение кода
  • подсказки при наборе кода (функции, ключевые слова, переменные, которые объявлял ранее)
  • и прочие

Как это поможет?

IDE знает, что она редактирует код и знает язык, на котором написан код. В неё встроен синтаксический анализатор языка программирования.

Еще на самом начальном этапе написания кода она может показать строки с банальными (и не только) ошибками, но которые уже могут привести к нерабочему или неправильно функционирующему коду.

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

Можно сразу видеть:

  • уровень ошибки (предупреждение, уведомление, ошибка)
  • полный текст ошибки
  • номер строки в том самом скрипте

Можно перейти в скрипт на указанную строку и проанализировать.

Не знаете английский?

Можете открыть любой онлайн переводчик и скопировать туда текст ошибки заменив заглавные буквы на строчные:

Error:(34, 9) java: cannot find symbol symbol: method getSum() location: class test.Test

Ошибка: (34, 9) java: не удается найти символ
Символ: метод getSum ()
Местоположение: класс test.Test

Откровенно по-русски говорит: не может найти метод getSum в классе test.Test на линии 34. Значит вызов есть, а объявления нет и искать надо в указанном направлении. Что еще от жизни надо?

Исправлять желательно все ошибки, как минимум уровня опасности "красный". warning и notice могут быть временно забыты, например сообщение о неиспользованной переменной, которую вы точно намерены потом использовать. Но в итоге надо починить их все!

В IDE еще много разных и полезных возможностей. Если желаешь себе зла — можешь продолжать писать в блокноте.

READ ALSO
Треугольник Паскаля на ArrayList

Треугольник Паскаля на ArrayList

Рабочий вариантВажно, что c = 1 в начале цикла для заполнения строк

263
Database Migration using Java

Database Migration using Java

Всем привет! Нужна помощь в принятии решения, заранее спасибо! Задача состоит в том, что нужно разработать инструмент(сервис) для миграции...

214
AsyncTask падает при парсинге html страницы

AsyncTask падает при парсинге html страницы

Суть приложения такова, что я ввожу какие-то символы, которыми дополняются определенный url и с этого url уже идет парсинг нужных мне значенийПри...

206
Проблема с Apache camel jaxb marshalling

Проблема с Apache camel jaxb marshalling

Добрый деньЧитаю Camel in Action, там есть пример маршаллинга в xml с помощью jaxb Spring XML

249