Ошибки компиляции
Компилятор — строгий корректор. Прежде чем партитура попадёт к оркестру, он проверяет каждую её строку. Найдя нарушение, корректор возвращает текст с пометками на полях, и концерт не начинается.
Вот программа, в которой забыта одна точка с запятой:
public class Main {
public static void main(String[] args) {
System.out.println("Hello");
System.out.println("Bye") // ✗
}
}error: ';' expectedЭто ошибка компиляции: компилятор отказался переводить текст, и программа не запустилась. Hello тоже не напечатано, хотя первая инструкция верная. Корректор вернул партитуру целиком, и оркестр не сыграл ни такта.
На собеседовании любят спрашивать, чем ошибка компиляции отличается от ошибки во время работы программы. Первую находит компилятор до запуска, и не выполняется ни одна строка. Вторая случается, когда программа уже работает и часть строк успела выполниться.
Как читать сообщение
Целиком первая строка сообщения выглядит так: Main.java:4: error: ';' expected. Разберём её слева направо:
Main.java— файл с ошибкой.4— номер строки.error: ';' expected— что нарушено: здесь ожидалась точка с запятой.
Под этой строкой javac повторяет строку программы и ставит знак ^ там, где заметил ошибку. В конце он пишет, сколько ошибок нашёл: 1 error. При запуске через java Main.java добавляется ещё строка error: compilation failed — «компиляция не удалась».
Неизвестное имя
Вторая частая ошибка — имя, которого Java не знает. Здесь в имени метода пропущена буква:
System.out.printn("Hi"); // ✗error: cannot find symbol
symbol: method printn(String)
location: variable out of type PrintStreamcannot find symbol значит «имя не найдено». Две строки под ним уточняют, что и где искали:
symbol— какое имя не найдено: методprintn, которому передали строку;location— где его искали: вSystem.out;PrintStream— класс, в котором лежатprintиprintln.
Исправьте имя на println, и программа скомпилируется.
Здесь картинка с корректором неточна. Настоящий корректор заметил бы и опечатку в слове "Helo". Компилятор проверяет правила и имена языка, а текст в кавычках не читает: println("Helo") он пропустит, и опечатку вы увидите только в выводе.
Сначала первая ошибка
Одна ошибка может породить несколько сообщений. Здесь у текста забыли кавычки:
System.out.println(Hello Java); // ✗error: ')' or ',' expected
error: not a statement
error: ';' expectedБез кавычек компилятор читает Hello и Java как два имени подряд и запутывается: три сообщения на одну строку. Добавьте кавычки, "Hello Java", и пропадут все три.
Поэтому исправляйте ошибки сверху вниз. Исправив первую, запустите компиляцию снова: следующие сообщения часто исчезают вместе с ней.
Частая ошибка
Имя написали со строчной буквы:
system.out.println("Hi"); // ✗error: package system does not existJava различает регистр — заглавные и строчные буквы. System и system для неё два разных имени, и второго нет. Сообщение выглядит странно: javac решил, что system — пакет, группа классов, и такого пакета не нашёл. Но виновата всего одна строчная s.
Так же различаются String и string, main и Main. Имена в Java пишут ровно так, как их задали, буква в букву.
Главное
- Ошибку компиляции находит компилятор до запуска: программа не запускается, и не выполняется ни одна строка, даже верная.
- Сообщение
Main.java:4: error: …называет файл, номер строки и нарушенное правило. cannot find symbolзначит, что Java не знает имени; Java различает заглавные и строчные буквы во всех именах.- Исправляйте первую ошибку первой: остальные сообщения часто исчезают вместе с ней.