1. Обзор
В этом учебнике мы рассмотрим, что такое ошибки компиляции, а затем конкретно объясним, что такое ошибка «не может найти символ» и как она вызвана.
2. Ошибки времени компиляции
Во время компиляции компилятор анализирует и проверяет код на многие вещи; типы ссылок, слепки типов и объявления методов, чтобы назвать несколько. Эта часть процесса компиляции важна, так как на этом этапе мы получим ошибку компиляции.
В основном существует три типа ошибок времени компиляции:
- У нас могут быть синтаксисные . Одна из наиболее распространенных ошибок, которые может сделать любой программист, это забыть поставить заоколонку в конце заявления; некоторые другие забывают импорт, несоответствие скобки, или опуская заявление о возвращении
- Далее, есть ошибки проверки типов. Это процесс проверки безопасности типов в нашем коде. С помощью этой проверки мы убеждаемся, что у нас есть последовательные типы выражений. Например, если мы определяем переменную типа int , мы никогда не должны назначать двойной или Струнные значение для него
- Между тем, существует вероятность того, что компилятор . Это очень редко, но это может произойти. В этом случае хорошо знать, что наш код не может быть проблемой, но что это скорее внешняя проблема
3. Ошибка “не может найти символ”
Ошибка “не может найти символ” возникает в основном, когда мы пытаемся использовать переменную, которая не определена или объявлена в нашей программе.
Когда наш код компилирует, компилятор должен проверить все идентификаторы, которые у нас есть. Ошибка “не может найти символ” означает, что мы ссылаясь на то, что компилятор не знает о .
3.1. Что может вызвать ошибку «не может найти символ»?
Действительно, есть только одна причина: Компилятор не смог найти определение переменной, на которую мы пытаемся ссылаться.
Но, Есть много причин, почему это происходит. Чтобы помочь нам понять, почему, давайте напомним себе, из чего состоит Java-код.
Наш исходный код Java состоит из:
- Ключевые слова: правда, ложь, класс, в то время как
- Буквально: цифры и текст
- Операторы и другие не-альфа-токены: -,/,
- Идентификаторы: основные , Читатель , Я , toString и так далее.
- Комментарии и белое пространство
4. Опечатка
Наиболее распространенные вопросы связаны с орфографией. Если мы вспомним, что все идентификаторы Java чувствительны к случаям, мы можем видеть, что:
- Струнныйбиулдер
- строкаСтроитель
- String_Builder
все это будет по-разному способы неправильно ссылаться на Стрингбилдер класс.
5. Сфера применения экземпляра
Эта ошибка также может быть вызвана при использовании чего-то, что было объявлено вне сферы действия класса.
Допустим, у нас есть Статья класс, который вызывает generateId метод:
public class Article { private int length; private long id; public Article(int length) { this.length = length; this.id = generateId(); } }
Но, мы объявляем generateId метод в отдельном классе:
public class IdGenerator { public long generateId() { Random random = new Random(); return random.nextInt(); } }
С помощью этой настройки компилятор даст ошибку “не может найти символ” для generateId на линии 7 Статья обрезок. Причина в том, что синтаксис строки 7 подразумевает, что generateId метод объявляется в Статья .
Как и во всех зрелых языках, существует несколько способов решения этой проблемы. Но, один из способов было бы построить ИдГенератор в Статья класса, а затем вызвать метод:
public class Article { private int length; private long id; public Article(int length) { this.length = length; this.id = new IdGenerator().generateId(); } }
6. Неопределенные переменные
Иногда мы забываем объявить переменную. Как мы видим из фрагмента ниже, мы пытаемся манипулировать переменной мы не объявили, в данном случае, текстовые :
public class Article { private int length; // ... public void setText(String newText) { this.text = newText; // text variable was never defined } }
Мы решаем эту проблему, объявляя переменную текстовые типа Струнные :
public class Article { private int length; private String text; // ... public void setText(String newText) { this.text = newText; } }
7. Переменный охват
Когда переменная декларация выходит из сферы действия в момент, когда мы пытались использовать ее, это вызовет ошибку во время компиляции. Обычно это происходит, когда мы работаем с петлями.
Переменные внутри цикла недоступны за пределами цикла:
public boolean findLetterB(String text) { for (int i=0; i < text.length(); i++) { Character character = text.charAt(i); if (String.valueOf(character).equals("b")) { return true; } return false; } if (character == "a") { // <-- error! ... } }
если заявление должно идти внутри для петли если нам нужно изучить символы больше:
public boolean findLetterB(String text) { for (int i = 0; i < text.length(); i++) { Character character = text.charAt(i); if (String.valueOf(character).equals("b")) { return true; } else if (String.valueOf(character).equals("a")) { ... } return false; } }
8. Недействительное использование методов или полей
Ошибка “не может найти символ” также произойдет, если мы используем поле в качестве метода или наоборот:
public class Article { private int length; private long id; private Listtexts; public Article(int length) { this.length = length; } // getters and setters }
Теперь, если мы попытаемся сослаться на тексты поле, как если бы это был метод:
Article article = new Article(300); Listtexts = article.texts();
то мы увидим ошибку.
Это потому, что компилятор ищет метод под названием тексты , которого нет.
Вообще-то, есть getter метод, который мы можем использовать вместо этого:
Article article = new Article(300); Listtexts = article.getTexts();
Ошибка работы на массиве, а не элемент массива также является проблемой:
for (String text : texts) { String firstLetter = texts.charAt(0); // it should be text.charAt(0) }
И так забывает новые ключевое слово, как в:
String s = String(); // should be 'new String()'
9. Импорт пакетов и классов
Другая проблема заключается в том, чтобы забыть импортировать класс или пакет. Например, с помощью Список объект без импорта java.util.List :
// missing import statement: // import java.util.List public class Article { private int length; private long id; private Listtexts; <-- error! public Article(int length) { this.length = length; } }
Этот код не будет компилироваться, так как программа не знает, что Список ош
10. Неправильный импорт
Импорт неправильного типа, из-за завершения IDE или автоматической коррекции также является общей проблемой.
Подумайте о ситуации, когда мы хотим использовать даты в Java. Много раз мы могли бы импортировать неправильный Дата класс, который не предоставляет методы и функции, как другие классы даты, которые нам могут понадобиться:
Date date = new Date(); int year, month, day;
Чтобы получить год, месяц или день для java.util.Date , мы также должны импортировать Календарь класса и извлечь информацию оттуда.
Просто ссылаясь на getDate () из java.util.Date не будет работать:
... date.getDay(); date.getMonth(); date.getYear();
Вместо этого мы используем Календарь объект:
... Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris")); cal.setTime(date); year = cal.get(Calendar.YEAR); month = cal.get(Calendar.MONTH); day = cal.get(Calendar.DAY_OF_MONTH);
Однако, если мы импортировали Местное класса, нам не нужен дополнительный код, который предоставляет нам информацию, в которой мы нуждаемся:
... LocalDate localDate=date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); year = localDate.getYear(); month = localDate.getMonthValue(); day = localDate.getDayOfMonth();
11. Заключение
Компиляторы работают над фиксированным набором правил, которые являются специфическими для языка. Если код не придерживается этих правил, компилятор не может выполнить процесс преобразования, что приводит к ошибке компиляции. Когда мы сталкиваемся с ошибкой компиляции “Не может найти символ”, ключ должен определить причину.
Из сообщения об ошибке мы можем найти строку кода, где происходит ошибка, а какой элемент неправильный. Зная наиболее распространенные проблемы, вызывающие эту ошибку, сделает ее решение очень легко и быстро.