Администрирование
HyperSQL, IBM DB2, IBM DB2, Interbase, Firebird, Yaffil , MSSQL, MySQL, ORACLE, PostgreSQL, SYBASE, Другие, Курсы, ... |
Безопасность
HyperSQL, MSSQL, Oracle, Phpmyadmin, Инъекция SQL, Книги, Патчи, Программы, Скрипты, СУБД, ... |
Проектирование БД
Business intelligence, Data Warehouse, Designer 2000 (Oracle), ErWin, ETL, OLAP, Sybase PowerDesigner , Другие CASE средства, Статьи, Теория БД, ... |
Производительность
DB2, HyperSQL, IBM DB2, Interbase, Firebird, Yaffil, MSSQL, MySQL, ORACLE, PostgreSQL, SQL, SYBASE, Другие, ... |
Установка
HyperSQL, IBM DB2, Interbase, Firebird, Yaffil , MSSQL, MySQL, ORACLE, PostgreSQL, SYBASE, Другие, ... |
|
|
Главная Java Ошибки начинающих java-программистов
Ошибки начинающих java-программистов
|
|
|
|
Страница 1 из 3 
1. Имя класса отличается от имени файла, в котором он хранится.
Все используемые мною среды java, включая Javasoft JDKs, предполагают, что исходный код класса с модификатором public хранится в файле с точно аким же именем, как и имя класса, и расширением .java. Несоблюдение этого соглашения может стать причиной многих проблем, которые выявятся во время омпиляции. Начинающие студенты (программисты) часто забывают об этом соглашении, например, задают имя файла в соответствии с заданием: Lab6.java.
Ошибочный пример: Имя файла Lab6.java -
public class Airplane extends Vehicle Seat pilot; public Airplane() { pilot = new Seat(); } }
|
Исправленный пример: Имя файла Airplane.java -
public class Airplane extends Vehicle Seat pilot; public Airplane() { pilot = new Seat(); } }
|
Заметьте: предполагается, что имя класса начинается с заглавной буквы. В операционных системах, которые учитывают регистр символов в именах файлов, могут появиться дополнительные проблемы, особенно у студентов, изучающих Java под Unix, и привыкших к системе именования файлов в DOS. Класс MotorVehicle должен храниться в файле MotorVehicle.java, но не в файле motorvehicle.java.
2. Сравнение с помощью ==
В Java строки - это объекты класса java.lang.String. Оператор ==, применяемый к объектам, проверяет на равенство ссылки на объекты! Иногда студенты не понимают семантики оператора == и пытаются применить его для сравнения строк.
Ошибочный пример:
// проверим, равен ли первый аргумент "-a" if (args[0] == "-a") { optionsAll = true; }
|
Правильный способ сравнения 2х строк на равенство - это использование метода equals() класса java.lang.String. Он возвращает true, если строки одинаковой длины и состоят из одних и тех же символов. (Прим. перев.: вообще-то это не гарантирует равенство. На самом деле, equals проверяет, равны ли посимвольно 2 строки)
Исправленный пример:
// проверим, равен ли первый аргумент "-a" if ("-a".equals(args[0])) { optionsAll = true; }
|
Эта ошибка - дурацкая, потому что на самом деле Java код получается синтаксически правильным, а в итоге работает не так как нужно. Некоторые студенты также пытаются применять операторы сравнения > и <=, вместо метода compareTo() класса java.lang.String. Эту ошибку обнаружить проще, потому что она вызывает ошибки на этапе компиляции.
3. Забыл проинициализировать объекты, являющиеся элементами массива.
В Java массив объектов - это на самом деле массив ссылок на объекты. Создание массива - это просто создание набора ссылок, ни на что не указывающих (то есть равных null). Чтобы на самом деле создать "полноценный" массив объектов, необходимо проинициализировать каждый элемент массива. Многие студенты не понимают этого; они считают, что, создавая массив объектов, они автоматически создают сами объекты. (В большинстве случаев, студенты приносят эту концепцию из C++, где создание массива объектов приводит к созданию самих объектов путем вызова их конструктора по умолчанию).
В примере ниже, студент хочет создать 3 объекта класса StringBuffer. Код будет откомпилирован без ошибок, но в последней строке произойдет исключение NullPointerException, где происходит обращение к несуществующему объекту.
Ошибочный пример:
// Создаем массив из StringBuffer StringBuffer [] myTempBuffers; myTempBuffers = new StringBuffer[3]; myTempBuffers[0].add(data);
|
Чтобы не допускать эту ошибку, необходимо не забывать проинициализировать элементы массива.
Исправленный пример:
// Создаем массив из StringBuffer и инициализируем элементы StringBuffer [] myTempBuffers; myTempBuffers = new StringBuffer[3]; for (int ix = 0; ix < myTempBuffers.length; ix++) myTempBuffers[ix] = new StringBuffer();
myTempBuffers[0].add(data);
|
4. Помещение в один файл сразу нескольких классов с модификатором public
Файлы с исходным java-кодом определенным образом связаны с классами, содержащимися в этих файлах. Связь можно охарактеризовать так:
Любой Java-класс хранится не более чем в одном файле В любой файл с исходным кодом можно поместить не более 1-го класса с модификатором public Если в файле с исходным кодом есть класс с модификатором public, имя файла и имя класса должны быть строго одинаковыми (прим. перев.: до регистра, см. п.1)
Иногда студенты забывают о 2-ом правиле, что приводит к ошибкам на этапе компиляции. Сообщение об ошибке для 2-го и 3-го правила будет одинаковым (в чем собственно и заключается трудность распознания этой ошибки).
5. Подмена поля класса локальной переменной.
Java позволяет объявлять внутри метода переменные, чье имя совпадает с полями класса. В таком случае преимущество будет отдано локальным переменным, и они будут использоваться вместо полей.
Компилятор выдаст ошибку, если переменные с одинаковыми именами будут разных типов. Если же они одинаковых типов, ошибки компиляции не будет, и будут непонятны причины неправильной работы программы.
Ошибочный пример:
public class Point3 { int i = 0; int j = 0; int k = 0;
public boolean hits(Point[] p2list) { for(int i = 0; i < p2list.length; i++) { Point p2 = p2list[i]; if (p2.x == i && p2.y == j) return true; } return false; } }
|
Есть несколько способов, как исправить эту ошибку. Наиболее простой - обращаться к полям класса с помощью неявного указателя this: this.имя_поля. Более лучший способ - это переименовать поле класса или локальную переменную, тогда подмены не произойдет. (прим. перев.: 2-ой способ - не наш метод. К тому же он не гарантирует, что я когда нибудь случайно не подменю поле переменной. Еще большая трудность возникнет при наследовании, когда я вообще не вижу, какие поля есть у класса)
Исправленный пример:
// One way to fix the problem int i = 0; int j = 0; int k = 0;
public boolean hits(Point[] p2list) { for(int i = 0; i < p2list.length; i++) { Point p2 = p2list[i]; if (p2.x == this.i && p2.y == this.j) return true; } return false; }
// ***************************** // Более лучший способ int x = 0; int y = 0; int z = 0;
public boolean hits(Point[] p2list) { for(int i = 0; i < p2list.length; i++) { Point p2 = p2list[i]; if (p2.x == x && p2.y == y) return true; } return false; }
|
Еще одно возможное место появления этой ошибки - задание имени параметра метода таким же, как и имя поля класса. Это хорошо выглядит в конструкторах, но для обычных методов не подходит.
| прим. перев. | немного сумбурно, но смысл такой
public class Test { private int param = 0;
public Test(int param) { this.param = param; } }
| то есть в конструкторе все смотрится красиво, но для обычных методов применять это не следует.
|
6. Забыл вызвать конструктор родителя (суперкласса).
Когда класс расширяет другой класс, каждый конструктор подкласса должен вызвать какой-либо конструктор суперкласса. Обычно это достигается вызовом конструктора суперкласса методом super(x), помещенным в первой строке конструктора. Если в первой строке конвтруктора нет вызова super(x), компилятор самостоятельно вставляет этот вызов, но без параметров: super(). (прим. перев.: х...се, а я и не знал )
Иногда студенты забывают об этом требовании. Обычно это не является проблемой: вызов конструктора суперкласса вставляется компилятором и все работает отлично. Однако если у суперкласса нет конструктора по умолчанию (прим. перев.: то есть конструктора без параметров), то компилятор выдаст ошибку. В примере ниже все конструкторы суперкласса java.io.File имеют 1 или 2 параметра:
Ошибочный пример:
public class JavaClassFile extends File { String classname; public JavaClassFile(String cl) { classname = cl; } }
|
Решением проблемы является вставка явного вызова правильного конструктора суперкласса:
Исправленный пример:
public class JavaClassFile extends File { String classname; public JavaClassFile(String cl) { super(cl + ".class"); classname = cl; } }
|
Более неприятная ситуация возникает, когда у суперкласса есть конструктор по умолчанию, но он не полностью инициализирует объект. В таком случае код скомпилируется, но результат работы программы может быть неправильным или может возникнуть исключение.
7. Неправильный перехват исключений
Система обработки исключений в Java достаточно мощная, но трудная для понимания новичками. Студенты, хорошо владеющие C++ или Ada, обычно не испытывают сложностей, в отличие от программистов C и Fortran. Примеры ниже показывают некоторые распространенные ошибки.
В данном примере для исключения не указано имя. На эту ошибку укажет компилятор на этапе компиляции, так что ее легко исправить самостоятельно.
Ошибочный пример:
try { stream1 = new FileInputStream("data.txt"); } catch (IOException) { message("Could not open data.txt"); }
|
Исправленный пример:
try { stream1 = new FileInputStream("data.txt"); } catch (IOException ie) { message("Could not open data.txt: " + ie); }
|
Порядок расположения блоков catch определяет очередность перехвата исключений. Нужно учитывать, что каждый такой блок перехватит все исключения указанного класса или любого его подкласса. Если не учесть это, то можно получить недостижимый блок catch, на что укажет компилятор. В примере ниже SocketException является подклассом IOException.
Ошибочный пример:
try { serviceSocket.setSoTimeout(1000); newsock = serviceSocket.accept(); } catch (IOException ie) { message("Error accepting connection."); } catch (SocketException se) { message("Error setting time-out."); }
|
Исправленный пример:
try { serviceSocket.setSoTimeout(1000); newsock = serviceSocket.accept(); } catch (SocketException se) { message("Error setting time-out."); } catch (IOException ie) { message("Error accepting connection."); }
|
Если в коде возможно появление исключения, которое не перехватавается ни одним блоком try-catch, то это исключение следует объявить в заголовке метода. (Для исключений - подклассов класса RuntimeException это не обязательно). Студенты иногда забывают о том, что вызов метода может порождать исключение. Проще всего это исправить, помещая вызов метода в блок try-catch.
Ошибочный пример:
public void waitFor(int sec) { Thread.sleep(sec * 1000); }
|
Исправленный пример:
public void waitFor(int sec) throws InterruptedException { Thread.sleep(sec * 1000); }
|
8. Метод доступа имеет тип void
Это очень простая ошибка. Студент создает метод для доступа к переменной, но указывает, что метод ничего не возвращает (помещает модификатор void в загогловок метода). Чтобы исправить эту ошибку, нужно указать правильный тип возвращаемого значения.
Ошибочный пример:
public class Line { private Point start, end; public void getStart() { return start; } }
|
Исправленный пример:
public class Line { private Point start, end; public Point getStart() { return start; } }
|
Указание неправильного возвращаемого типа порождает целый класс ошибок. Обычно компилятор распознает эти ошибки и сообщает о них, так что студенты могут самостоятельно их исправить.
9. Вызов нестатичных методов класса из метода main()
Входной точкой любой Java программы должен быть статичный метод main:
public static void main(String[] args) { ... }
|
Так как этот метод статичный, нельзя из него вызывать нестатичные методы класса. Об этом часто забывают студенты и пытаются вызывать методы, не создавая экземпляр класса. Эту ошибку обычно допускают в самом начале обучения, когда студенты пишут маленькие программы.
Ошибочный пример:
public class DivTest { boolean divisible(int x, int y) { return (x % y == 0); }
public static void main(String[] args) { int v1 = 14; int v2 = 9;
// на следующие строки компилятор выдаст ошибку if (divisible(v1, v2)) { System.out.println(v1 + " is a multiple of " + v2); } else { System.out.println(v2 + " does not divide " + v1); } } }
|
Есть 2 способа исправления ошибки: сделать нужный метод статичным
|
|
Взаимосвязанные статьи |
-
Установка БД Oracle 9.2.0.4.0 на RED HAT Enterprise Linux AS 3 (x86)
-
Доступ к базам данных на стороне клиента. Java-технология
-
Сравнительный анализ .NET против. Java
-
Кодировка в Java. Русские буквы
-
Динамическая графика в Java сервлетах
-
Краткое введение в технологию Enterprise JavaBeans
-
Особенности реализации типа byte в Java Sun's J2SDK
-
Совместная отладка Java и C/C++ кода.
-
Сборка сервера JBoss 3.x из исходного кода
-
NewEra - новая линия инструментальных средств компании Informix
-
Применение CASE-средства ERwin для информационного моделирования в системах обработки данных
-
Рефакторинг SQL-запросов
-
Cинтаксис cтруктура XML
-
Работа с XML - сообщениями
-
Выдача данных из программы на PL/SQL в формате MS Word
-
Абстракция данных в языке С++
-
Создание Java-апплета для отображения географических карт
-
Восемь мифов про Java
-
Реляционные базы данных и язык SQL
-
SQL запросы с использованием единственной таблицы
-
SQL запросы с использованием нескольких таблиц
-
Агрегирование данных в SQL запросах
-
Вложенные SQL подзапросы
-
SQL запросы с использованием единственной таблицы
-
SQL запросы с использованием нескольких таблиц
-
Агрегирование данных в SQL запросах
-
Вложенные SQL подзапросы
-
Модификации данных SQL. Delete, Update, Insert
-
Реляционные базы данных и язык SQL
-
Рефакторинг SQL-запросов
-
Правил разработки SQL программ
-
Введение в язык PL/SQL
-
Курсоры PL/SQL
-
Oбработка исключений в PL/SQL
-
Пакеты PL/SQL
-
PL/SQL программирование. Взаимодействие с ORACLE
-
Краткий справочник по Transact SQL
-
Как проследить за выполнением программ PLSQL в Oracle
-
Как использовать календарь в Oracle Developer
-
Импорт данных из DBF файла в Oracle Developer
-
AllFusion ERwin Data Modeler 7 (ERwin)
-
Oracle Real Time Decisions - анализ данных в режиме реального времени
-
Моделирование групп объектов в Oracle
-
Импорт данных из DBF файла в Oracle Developer
-
Введение в хранилища данных Oracle
-
Новая семантика SQL:1999 (SQL3)
-
Суррогатные ключи. Конвейерная обработка суррогатных ключей
-
Наиболее интересные новшества в стандарте SQL:2003
-
Порядок разработки ETL - процессов для наполнения хранилища данных (ХД)
-
Наиболее интересные новшества в стандарте SQL:2003
-
Операторы Inner Join и Outer (left, right, full) Join в SQL (Oracle)
-
MDX Specification
-
PostgreSQL версии 8.0 Транзакции – точки сохранения – помогут сохранить ваши данные
-
Язык MDX
-
Hibernate 3.2 Transformers for HQL and SQL
-
Хранимые процедуры для Java-программистов
-
Объяснение SQL объединений JOIN INNER OUTER
-
Порядок разработки ETL - процессов для наполнения хранилища данных (ХД)
-
Как использовать список выбора в Oracle Developer
-
Операторы Inner Join и Outer (left, right, full) Join в SQL (Oracle)
-
Как правильно писать SQL-запросы
-
Макросы ERwin
-
Основные Свойства ERwin
-
Сущности и Атрибуты ER ERwin
-
Редактирование Графических Объектов ERwin
-
Связи в ERwin и Соответствующие Редакторы
-
Области (Subject Area) и Хранимые Изображения ERwin
-
Шрифты и Цвета ERwin
-
Сущности и Атрибуты: Возможности Повышенного Уровня Сложности ERwin
-
Документирование Правил (Business Rules) ERwin
-
Дополнительные Возможности Демонстрации Изображений ERwin
-
Задание Информации, Ориентированной на Субд ERwin
-
Задание Объектов Физической Памяти ERwin
-
Индексирование Таблиц Базы Данных ERwin
-
Триггеры и Хранимые Процедуры ERwin
-
Отчеты В Erwin
-
Прямое и Обратное Проектирование в Erwin
-
Импорт и Экспорт Без Использования SQL в Erwin
-
Сохранение Моделей Erwin в Базе Данных
-
Соответствие Типов Данных в Erwin
-
Новые возможности T-SQL в MS SQL Server 2005
-
Подсчёт отличающихся значений в языке MDX
-
Оптимизация MDX-формул вида Count(Filter(…))
-
Особенности условия NOT EXISTS пользователи языка SQL
-
Потоки данных в Oracle
-
Adding a default value to a column on a table
-
Большие объекты в СУРБД ORACLE. BLOB, CLOB
-
Краткое описание языка запросов Transact-SQL
-
Описание общих таблиц 1С V77 MS SQL
-
Производительность PL/SQL
-
ETL Kettle Tip: Using java locales for a Date Dimension
-
Job scheduling from Oracle 10g with dbms_scheduler
-
Проблема удаления дублей в таблицах Oracle
-
Writing Better SQL Using Regular Expressions ORACLE
-
Самые основы J2ME, необходимый инструментарий, установка - настройка, написание Hello World
-
Введение в сервлеты
-
JBuilder для начинающих
-
Создание Java-апплета для отображения географических карт
-
How To Replicate the Replace Built-In for CLOBs
-
Тип данных TIME в Oracle
-
Performance tuning of SQL Queries
-
SQL Analytic functions by Example (Oracle)
-
CronTrigger Tutorial (Java Quartz 1.7.3)
-
Почему SQL
-
Обработка транзакций
-
Для чего вообще нужен оператор JOIN?
-
Что быстрей LEFT JOIN или подзапрос в SELECT
-
Рекурсивные (Иерархические) запросы
-
Организация кросстабличной зависимости в PostgreSQL
-
Основы SQL: запросы к базе данных
-
Введение в SQL
-
Типы данных SQL
-
Типы привилегий Объектная и системные привилегии
-
SQL команды
-
Библиотека полезных функций для PostgreSQL
-
СУБД Hyper SQL
-
Стандартные исключения PLSQL
-
Выбор ячеек и диапазонов ячеек в Excel с помощью процедур Visual Basic
-
Excel's Dynamic Range Names
-
How to Loop in Cell Range in Excel
-
Описание ограничений при работе с массивами в Excel
-
Oracle JDeveloper 10g - Среда разработки Java приложений
-
How to send and receive files using FTP from within VBA
-
VBA Upload File Using FTP
-
How can you use an Oracle ref cursor in Java?
-
Oracle: употребление ссылки на курсор в программе
-
Примеры использования HIBERNATE Native SQL для выборки информации из базы данных
-
Hibernate. Создание named query или именованых запросов.
-
Использование объектных типов в PL/SQL
-
XML в Oracle - это очень просто
-
Объектные технологии в продуктах Oracle
-
Object Oriented PL/SQL Programming
-
Send e-mail from Oracle via the UTL_MAIL package
-
Временные таблицы в Oracle
-
Стандартные исключения PLSQL
-
PLSQL Пакет для работы с файловой системой на сервере
-
Уровни изолированности транзакций
-
How To configure the C3P0 connection pool
-
Hibernate: Providing Connections for Hibernate
-
Improving Hibernate's Performance
-
Разработка успешных приложений для Oracle
-
Проталкивание условия в представлениях, содержащих аналитические функции
-
Dependency Management - Dependencies in Server-Side PL/SQL
-
Стандартные пакеты. DBMS_JOB
-
Функции ROLLUP и CUBE в предложении SELECT
-
Работа с операторами SQL
-
Примеры использования HIBERNATE Native SQL для выборки информации из базы данных
-
Как проследить за выполнением программ в Oracle
-
Иерархические (рекурсивные) запросы
-
Библиотека dklab_rowlog для версионирования строк в таблицах PostgreSQL
-
Простой подход к версионированию баз данных MS SQL Server
-
SQLite и полноценный UNICODE
-
Partition outer join in oracle 10g
-
Quoting string literals in 10g
-
Merge enhancements in 10g
-
Pls-00436 removed in oracle 11g
-
How to create package runstats_pkg
-
The collect function in 10g
-
Forall enhancements in 10g
-
Aggregating data with the returning clause
-
Collection extensions in 10g
-
Regular expressions in 10g
-
Временные таблицы в ORACLE GLOBAL TEMPORARY
-
How To Use Oracle SQL: Learning SQL
-
Use UTL_FILE.IS_OPEN to see if file exists?
-
Using ORACLE Analytic Functions in Reports
-
PL/SQL Developer 8.0 Portable
|
|
Последние добавленные статьи |
|
|
|
|
|