| Работа над ошибками |
|
|
Sunday, 05 March 2006 | Сайт SQL.ru для раздела Ученье – свет От редакции IsraMir’а: чрезвычайно это полезная и нужная ведь: «разбор полетов», особенно, когда речь идет о начинающих изучать любое дело, в том числе и работу на Java. Именно поэтому материал, который я нашел и предлагаю вам сегодня (частично), показался мне очень полезным. Естественно, что наши решпекты и благодарности автору и владельцам сайта – на этот раз SQL.ruЭта статья создана из топика ошибки начинающих java-программистов.
Оригинал статьи здесь: http://users.erols.com/ziring/java-npm.html Перевод: Deady Имя класса отличается от имени файла, в котором он хранится. Все используемые мною среды java, включая Javasoft JDKs, предполагают, что исходный код класса с модификатором public хранится в файле с точно таким же именем, как и имя класса, и расширением .java. Несоблюдение этого соглашения может стать причиной многих проблем, которые выявятся во время компиляции. Начинающие студенты (программисты) часто забывают об этом соглашении, и, например, задают имя файла в соответствии с заданием: Lab6.java. Ошибочный пример: Имя файла Lab6.java
Исправленный пример: Имя файла Airplane.java
Заметьте: предполагается, что имя класса начинается с заглавной буквы. В операционных системах, которые учитывают регистр символов в именах файлов, могут появиться дополнительные проблемы, особенно у студентов, изучающих Java под Unix, и привыкших к системе именования файлов в DOS. Класс MotorVehicle должен храниться в файле MotorVehicle.java, но не в файле motorvehicle.java. Сравнение с помощью == В Java строки - это объекты класса java.lang.String. Оператор ==, применяемый к объектам, проверяет на равенство ссылки на объекты! Иногда студенты не понимают семантики оператора == и пытаются применить его для сравнения строк. Ошибочный пример:
Правильный способ сравнения 2-х строк на равенство – это использование метода equals() класса java.lang.String. Он возвращает true, если строки одинаковой длины и состоят из одних и тех же символов. (Прим. перев.: вообще-то это не гарантирует равенство. На самом деле, equals проверяет, равны ли посимвольно 2 строки) Исправленный пример:
Эта ошибка - дурацкая, потому что на самом деле Java код получается синтаксически правильным, а в итоге работает не так как нужно. Некоторые студенты также пытаются применять операторы сравнения > и <=, вместо метода compareTo() класса java.lang.String. Эту ошибку обнаружить проще, потому что она вызывает ошибки на этапе компиляции. Забыл проинициализировать объекты, являющиеся элементами массива. В Java массив объектов - это на самом деле массив ссылок на объекты. Создание массива - это просто создание набора ссылок, ни на что не указывающих (то есть равных null). Чтобы на самом деле создать "полноценный" массив объектов, необходимо проинициализировать каждый элемент массива. Многие студенты не понимают этого; они считают, что, создавая массив объектов, они автоматически создают сами объекты. (В большинстве случаев, студенты приносят эту концепцию из C++, где создание массива объектов приводит к созданию самих объектов путем вызова их конструктора по умолчанию). В примере ниже, студент хочет создать 3 объекта класса StringBuffer. Код будет откомпилирован без ошибок, но в последней строке произойдет исключение NullPointerException, где происходит обращение к несуществующему объекту. Ошибочный пример:
Чтобы не допускать эту ошибку, необходимо не забывать проинициализировать элементы массива. Исправленный пример:
Помещение в один файл сразу нескольких классов с модификатором public Файлы с исходным java-кодом определенным образом связаны с классами, содержащимися в этих файлах. Связь можно охарактеризовать так:
Иногда студенты забывают о 2-ом правиле, что приводит к ошибкам на этапе компиляции. Сообщение об ошибке для 2-го и 3-го правила будет одинаковым (в чем собственно и заключается трудность распознания этой ошибки). Подмена поля класса локальной переменной.
Java позволяет объявлять внутри метода переменные, чье имя совпадает с полями класса. В таком случае преимущество будет отдано локальным переменным, и они будут использоваться вместо полей. Компилятор выдаст ошибку, если переменные с одинаковыми именами будут разных типов. Если же они одинаковых типов, ошибки компиляции не будет, и будут непонятны причины неправильной работы программы. Ошибочный пример:
Есть несколько способов, как исправить эту ошибку. Наиболее простой - обращаться к полям класса с помощью неявного указателя this: this.имя_поля. Более лучший способ - это переименовать поле класса или локальную переменную, тогда подмены не произойдет. (прим. перев.: 2-ой способ - не наш метод. К тому же он не гарантирует, что я когда нибудь случайно не подменю поле переменной. Еще большая трудность возникнет при наследовании, когда я вообще не вижу, какие поля есть у класса) Исправленный пример:
Еще одно возможное место появления этой ошибки - задание имени параметра метода таким же, как и имя поля класса. Это хорошо выглядит в конструкторах, но для обычных методов не подходит.
На этом – все. Пока. На сегодня. Продолжение – следует. |
||||||||||||