Воскресенье, 2024-05-19, 11:50 PM

 

  Приветствую Вас, guest · RSS
 
Выход Мой профиль    Начало     Новые сообщения     Участники     Правила форума     Поиск     RSS  
 
  • Страница 1 из 1
  • 1
форум\forum » Компьютерное » Программирование » Java2 (язык програмирования java)
Java2
ProgerДата: Среда, 2006-11-01, 12:57 PM | Сообщение # 1
Administrator
Группа: Администраторы
Сообщений: 44
Репутация: 0
Статус: Offline
Я пожалуй начно с элементарного FAQ по Java2 или как его ещё называют JDK

1. Вопрос: Посоветуйте книги по Java
Quote
Ответ:

Bruce Eckel "Thinking in Java"

Кей С. Хорстман, Гари Корнелл. Java2. Библиотека профессионала. 2 тома.
По Servlets и JSP:

М. Холл. Сервлеты и JavaServer Pages.

Дэвид М. Гери. JavaServer Pages.

2. Вопрос: Где можно скачать Java, документацию к Java и средства разработки?

Quote
Ответ: Официальный сайт: http://java.sun.com, раздел Downloads. Документация там же: API Specifications

Дополнительно: Java documentations in Windows Help format

Среды разработки:

Eclipse: http://eclipse.org/

Borland JBuilder: http://www.borland.com/us/products/jbuilder/index.html

IntelliJ IDEA: http://www.jetbrains.com/idea

IntelliJ IDEA EAP (что это такое): http://www.intellij.net/eap/

Oracle JDeveloper: http://www.oracle.com/technology/software/products/jdev/index.html

Sun Java Studio Creator: http://developers.sun.com/prodtech/javatools/jscreator/index.jsp

Sun Java Studio Enterprise: http://www.sun.com/software/products/jsenterprise/index.xml
(Get Sun Java Studio Creator 2004Q2 and Sun Java Studio Enterprise 8 for FREE!)

Sun NetBeans: http://www.netbeans.info/downloads/download.php?a=b&p=1

3. Вопрос: Я написал класс. Как мне его скомпилировать и выполнить.
Quote
Ответ: Пример работы в консоли.

Test.java

public class Test {
public static void main(String[] args) {
System.out.println("test");
}
}

Компилирование:

javac Test.java

Выполнение:

java Test

Распространенные ошибки:

Для выполнения имя файла следует указывать без расширения.

для компиляции и выполнения в переменной среды CLASSPATH должен быть указан каталог расположения класса. При несоблюдении этого получим:

Exception in thread "main" java.lang.NoClassDefFoundError: Test

Дополнительно определяется понятие "текущий каталог", через точку. Все это можно указать либо в переменной среды CLASSPATH, либо при запуске javac и java как значение ключа -classpath. Например, команды для компиляции и запуска классов из текущего католога могут выглядеть так:

javac -classpath . Test.javajava -classpath . Test

4. Вопрос: Как мне преобразовать строку (String) в int, double и т.п.? Как обработать ошибку перевода (например, приравнивать к нулю в случае ее возникновения)?
Quote
Ответ: Смотрите статические методы parseXXX() соответствующих классов Integer, Double и т.д.:

int i = Integer.parseInt("16");
double d = Double.parseDouble("3.1415926");
// Обработка ошибки преобразования строки в число.
String doublestr = "1.2353462364534";
double num;
try {
num = Double.parseDouble(doublestr);
} catch (NumberFormatException e) {
num = 0.0; //в случае ошибки перевода
}

5. Вопрос: Как мне преобразовать строку (String) в дату (java.util.Date, java.sql.Date)? Как отформатировать дату в нужном мне виде?
Quote
Ответ: Используйте класс SimpleDateFormat.

import java.util.Date;
import java.text.SimpleDateFormat;
...
// Преобразование строки в дату.
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
Date date = formatter.parse("01.02.2006 12:34:56");
// Преобразование даты в строку.
SimpleDateFormat formatter2 = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss");
String stDate = formatter2.format(new Date());

6. Вопрос: Как подключиться и работать с базами данных? Какие требуются библиотеки для работы с базами данных? Как сформировать строку соединения для подключения к БД?

Quote
Ответ: Используйте Java Database Connectivity Drivers (драйвера JDBC). Для каждой из БД, как правило, есть свой драйвер. Под Windows можно использовать JDBC-ODBC-мост, идущий в составе JDK:

http://java.sun.com/j2se....oc.html
Доступ к базам данных из Java-программ и проблемы русификации

JDBC-драйвера:

Firebird: Firebird Class 4 JCA-JDBC Driver Downloads

MSSQL: SQL Server 2000 Driver for JDBC, SQL Server 2005 JDBC Driver, jTDS - SQL Server and Sybase JDBC driver

MySQL: MySQL Connector/J

Oracle: JDBC, SQLJ, and Oracle JPublisher

Sybase: jTDS - SQL Server and Sybase JDBC driver

Списки JDBC-драйверов: JDBC Technology - Drivers, JDBC Drivers and Vendors

Строки соединения смотрите по каждому драйверу отдельно. Дополнительно можно взглянуть на Описание синтаксиса использования различных JDBC драйверов

7. Вопрос: Как при запуске java не показывать консольное окно?

Quote
Ответ: Вместо %JAVA_HOME%\bin\java используйте %JAVA_HOME%\bin\javaw

8. Вопрос: Как управлять настройками Java-машины, например, увеличить объем выделяемой памяти? Какие бывают параметры запуска JVM?

Quote
Ответ: A Collection of JVM Options, The most complete list of -XX options for Java 6 JVM

9. Вопрос: Как из исходника java-класса (.java) или скомпилированного java-класса (.class) сделать исполняемый файл (exec для Windows), не требующий JRE?

Quote
Ответ: Поиск по ключевым словам "java to native":
Google Directory - Computers > Programming > Languages > Java > Development Tools > Translators > Java To Other
Free Java Compilers, Assemblers & Java Development Kits (JDK)

Java to EXE - Why, When, When Not and How

Если после прочтения вами кокого либо материала из данной статьи у вас появились вопросы то не стисняйтесь и задавайти их я с большим удовольствеем отвечу на них.

PS: В следующей раз я покажу как написать илементарную программу на java2 с подробными коминтариями!!!


 
ProgerДата: Среда, 2006-11-08, 7:34 PM | Сообщение # 2
Administrator
Группа: Администраторы
Сообщений: 44
Репутация: 0
Статус: Offline
Ошибки начинающих java-программистов

1. Имя класса отличается от имени файла, в котором он хранится.

Quote
Все используемые мною среды java, включая Javasoft JDKs, предполагают,
что исходный код класса с модификатором public хранится в файле с точно
таким же именем, как и имя класса, и расширением .java. Несоблюдение этого
соглашения может стать причиной многих проблем, которые выявятся во время
компиляции.

Начинающие студенты (программисты) часто забывают об этом соглашении,
и, например, задают имя файла в соответствии с заданием: Lab6.java.

Code
Ошибочный пример: Имя файла Lab6.java -
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() { 
   pilot = new Seat(); 
  }
}

 

[code]Исправленный пример: Имя файла Airplane.java -
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() { 
   pilot = new Seat(); 
  }
}


Заметьте: предполагается, что имя класса начинается с заглавной буквы. В
операционных системах, которые учитывают регистр символов в именах файлов,
могут появиться дополнительные проблемы, особенно у студентов, изучающих
Java под Unix, и привыкших к системе именования файлов в DOS. Класс
MotorVehicle должен храниться в файле MotorVehicle.java, но не в файле
motorvehicle.java.

2. Сравнение с помощью ==

Quote
В Java строки - это объекты класса java.lang.String. Оператор ==, применяемый
к объектам, проверяет на равенство ссылки на объекты! Иногда студенты не
понимают семантики оператора == и пытаются применить его для сравнения
строк.

Code
Ошибочный пример: 
// проверим, равен ли первый аргумент "-a"
if (args[0] == "-a") {
   optionsAll = true;
}
[/code]

Правильный способ сравнения 2х строк на равенство - это использование метода
equals() класса java.lang.String. Он возвращает true, если строки одинаковой
длины и состоят из одних и тех же символов. (Прим. перев.: вообще-то это не
гарантирует равенство. На самом деле, equals проверяет, равны ли посимвольно
2 строки)

Code
Исправленный пример:
// проверим, равен ли первый аргумент "-a"
if ("-a".equals(args[0])) {
   optionsAll = true;
}

Эта ошибка - дурацкая, потому что на самом деле Java код получается
синтаксически правильным, а в итоге работает не так как нужно. Некоторые
студенты также пытаются применять операторы сравнения > и <=, вместо метода compareTo() класса java.lang.String. Эту ошибку обнаружить
проще, потому что она вызывает ошибки на этапе компиляции.

3. Забыл проинициализировать объекты, являющиеся элементами массива.

Quote
В Java массив объектов - это на самом деле массив ссылок на объекты. Создание
массива - это просто создание набора ссылок, ни на что не указывающих (то
есть равных null). Чтобы на самом деле создать "полноценный" массив
объектов, необходимо проинициализировать каждый элемент массива. Многие
студенты не понимают этого; они считают, что, создавая массив объектов, они
автоматически создают сами объекты. (В большинстве случаев, студенты
приносят эту концепцию из C++, где создание массива объектов приводит к
созданию самих объектов путем вызова их конструктора по умолчанию).

В примере ниже, студент хочет создать 3 объекта класса StringBuffer. Код
будет откомпилирован без ошибок, но в последней строке произойдет
исключение NullPointerException, где происходит обращение к несуществующему
объекту.

Quote
Ошибочный пример:
// Создаем массив из StringBuffer
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
myTempBuffers[0].add(data);

Чтобы не допускать эту ошибку, необходимо не забывать проинициализировать
элементы массива.

Code
Исправленный пример:
// Создаем массив из 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. Подмена поля класса локальной переменной.

Quote
Java позволяет объявлять внутри метода переменные, чье имя совпадает с
полями класса. В таком случае преимущество будет отдано локальным
переменным, и они будут использоваться вместо полей.

Quote
Компилятор выдаст ошибку, если переменные с одинаковыми именами будут
разных типов. Если же они одинаковых типов, ошибки компиляции не будет, и
будут непонятны причины неправильной работы программы.

Code
Ошибочный пример: 
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-ой способ - не
наш метод. К тому же он не гарантирует, что я когда нибудь случайно не
подменю поле переменной. Еще большая трудность возникнет при
наследовании, когда я вообще не вижу, какие поля есть у класса)

Исправленный пример:

Code
// 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;
  }


Еще одно возможное место появления этой ошибки - задание имени параметра
метода таким же, как и имя поля класса. Это хорошо выглядит в конструкторах,
но для обычных методов не подходит.

прим. перев.

Code
немного сумбурно, но смысл такой
public class Test {
  private int param = 0;

  public Test(int param) {
    this.param = param;
  }
}



то есть в конструкторе все смотрится красиво, но для обычных методов
применять это не следует.

6. Забыл вызвать конструктор родителя (суперкласса).

Quote
Когда класс расширяет другой класс, каждый конструктор подкласса должен
вызвать какой-либо конструктор суперкласса. Обычно это достигается вызовом
конструктора суперкласса методом super(x), помещенным в первой строке
конструктора. Если в первой строке конвтруктора нет вызова super(x),
компилятор самостоятельно вставляет этот вызов, но без параметров: super().
(прим. перев.: х...се, а я и не знал
)

Иногда студенты забывают об этом требовании. Обычно это не является
проблемой: вызов конструктора суперкласса вставляется компилятором и все
работает отлично. Однако если у суперкласса нет конструктора по умолчанию
(прим. перев.: то есть конструктора без параметров), то компилятор выдаст
ошибку. В примере ниже все конструкторы суперкласса java.io.File имеют
1 или 2 параметра:

Code
Ошибочный пример: 
public class JavaClassFile extends File {
   String classname;
   public JavaClassFile(String cl) {
     classname = cl;
   }
}

Решением проблемы является вставка явного вызова правильного
конструктора суперкласса:

Code
Исправленный пример:
public class JavaClassFile extends File {
   String classname;
   public JavaClassFile(String cl) {
     super(cl + ".class");
     classname = cl;
   }
}

Более неприятная ситуация возникает, когда у суперкласса есть конструктор
по умолчанию, но он не полностью инициализирует объект. В таком случае
код скомпилируется, но результат работы программы может быть
неправильным или может возникнуть исключение.

7. Неправильный перехват исключений

Quote
Система обработки исключений в Java достаточно мощная, но трудная для
понимания новичками. Студенты, хорошо владеющие C++ или Ada, обычно не
испытывают сложностей, в отличие от программистов C и Fortran. Примеры ниже
показывают некоторые распространенные ошибки.

В данном примере для исключения не указано имя. На эту ошибку укажет
компилятор на этапе компиляции, так что ее легко исправить самостоятельно.

Ошибочный пример:

Code
try {
   stream1 = new FileInputStream("data.txt");
} catch (IOException) { 
   message("Could not open data.txt");
}

Code
Исправленный пример:
try {
  stream1 = new FileInputStream("data.txt");
} catch (IOException ie) { 
  message("Could not open data.txt: " + ie);
}

Порядок расположения блоков catch определяет очередность перехвата
исключений. Нужно учитывать, что каждый такой блок перехватит все
исключения указанного класса или любого его подкласса. Если не учесть
это, то можно получить недостижимый блок catch, на что укажет компилятор.
В примере ниже SocketException является подклассом IOException
.
Quote

Ошибочный пример:
try {
serviceSocket.setSoTimeout(1000);
newsock = serviceSocket.accept();
} catch (IOException ie) {
message("Error accepting connection.");
} catch (SocketException se) {
message("Error setting time-out.");
}

Code
Исправленный пример:
try {
   serviceSocket.setSoTimeout(1000);
   newsock = serviceSocket.accept();
} catch (SocketException se) {
   message("Error setting time-out.");
} catch (IOException ie) { 
   message("Error accepting connection.");
}

Quote
Если в коде возможно появление исключения, которое не перехватавается
ни одним блоком try-catch, то это исключение следует объявить в заголовке
метода. (Для исключений - подклассов класса RuntimeException это не
обязательно). Студенты иногда забывают о том, что вызов метода может
порождать исключение. Проще всего это исправить, помещая вызов метода в
блок try-catch.

Code
Ошибочный пример:
public void waitFor(int sec) {
   Thread.sleep(sec * 1000);
}

Code
Исправленный пример:
public void waitFor(int sec) throws InterruptedException {
   Thread.sleep(sec * 1000);
}

8. Метод доступа имеет тип void

Это очень простая ошибка. Студент создает метод для доступа к переменной,
но указывает, что метод ничего не возвращает (помещает модификатор void
в загогловок метода). Чтобы исправить эту ошибку, нужно указать правильный
тип возвращаемого значения
.

Code
Ошибочный пример: 
public class Line {
   private Point start, end;
   public void getStart() { 
    return start; 
   }
}

Code
Исправленный пример:
public class Line {
   private Point start, end;
   public Point getStart() { 
    return start; 
   }
}

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

9. Вызов нестатичных методов класса из метода main()

Входной точкой любой Java программы должен быть статичный метод main:
public static void main(String[] args) {
...
}

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

Code
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);
     }
   }
}


Quote
Есть 2 способа исправления ошибки: сделать нужный метод статичным
или создать экземпляр класса. Чтобы правильно выбрать нужный способ,
задайте себе вопрос: использует ли метод поля или другие методы класса.
Если да, то следует создать экземпляр класса и вызвать у него метод,
иначе следует сделать метод статичным.

Code
Исправленный пример 1:
public class DivTest {
   int modulus;

   public DivTest(int m) { 
    modulus = m; 
   }
   
   boolean divisible(int x) {
     return (x % modulus == 0);
   }

   public static void main(String[] args) {
     int v1 = 14;
     int v2 = 9;

     DivTest tester = new DivTest(v2);

     if (tester.divisible(v1) {
       System.out.println(v1 + " is a multiple of " + v2);
     } else {
       System.out.println(v2 + " does not divide " + v1);
     }
   }
}


Code
Исправленный пример 2:

public class DivTest {
   static 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);
     }
   }
}

 

10. Использование объектов класса String как параметров метода.
Quote

В Java класс java.lang.String хранит строковые данные. Однако, строки в Java
(1) обладают постоянством (то есть их нельзя изменять),
(2) являются объектами.

Поэтому с ними нельзя обращаться как просто с буфером символов, это
неизменяемые объекты. Иногда студенты передают строки, ошибочно
расчитывая на то, что строка-объект будет передана как массив символов
по ссылке (как в C или C++). Компилятор обычно не считает это ошибкой.

Code

Ошибочный пример.
public static void main(String args[]) {
  String test1 = "Today is ";
  appendTodaysDate(test1);
  System.out.println(test1);
}

/* прим. редактора: закомментированный метод должен иметь модификатор
   static (здесь автором допущена ошибка №9)
public void appendTodaysDate(String line) {
   line = line + (new Date()).toString();
}
*/

public static void appendTodaysDate(String line) {
   line = line + (new Date()).toString();
}


В примере выше студент хочет изменить значение локальной переменной test1,
присваивая новое значение параметру line в методе appendTodaysDate.
Естественно это не сработает. Значение line изменится, но значение test1
останется прежним.

Эта ошибка возникает из-за непонимания того, что (1) java объекты всегда
передаются по ссылке и (2) строки в Java неизменяемы. Нужно осмыслить, что
объекты-строки никогда не изменяют своего значения, а все операции над
строками создают новый объект.

Чтобы исправить ошибку в примере выше, нужно или возвращать строку из
метода, или передавать объект StringBuffer как параметр методу вместо String.

Исправленный пример 1:

Code
public static void main(String args[]) {
  String test1 = "Today is ";
  test1 = appendTodaysDate(test1);
  System.out.println(test1);
}

public static String appendTodaysDate(String line) {
   return (line + (new Date()).toString());
}

 

Исправленный пример 2:
public static void main(String args[]) {
  StringBuffer test1 = new StringBuffer("Today is ");
  appendTodaysDate(test1);
  System.out.println(test1.toString());
}

public static void appendTodaysDate(StringBuffer line) {
   line.append((new Date()).toString());
}


прим. перев.
вообще-то понять в чем ошибка не так просто.
так как объекты передаются по ссылке, то значит line ссылается туда же,
куда и test1. А значит создавая новый line, мы создаем новый test1.
в неправильном примере все выглядит так, как будто передача String идет
по значению, а не по ссылке.

11. Объявление конструктора как метода

Конструкторы объектов в Java внешне похожы на обычные методы. Единственные
отличия - у конструктора не указывается тип возвращаемого значения и
название совпадает с именем класса. К несчастью, Java допускает задание
имени метода, совпадающего с названием класса.

В примере ниже, студент хочет проинициализировать поле класса Vector list
при создании класса. Этого не произойдет, так как метод 'IntList' - это не
конструктор.

Code
Ошибочный пример.
public class IntList {
   Vector list;

   // Выглядит как конструктор, но на самом деле это метод
   public void IntList() {
     list = new Vector();
   }

   public append(int n) {
     list.addElement(new Integer(n));
   }
}


Quote
Код выдаст исключение NullPointerException при первом же ображении к полю
list. Ошибку легко исправить: нужно просто убрать возвращаемое значение
из заголовка метода.

Code
Исправленный пример:
public class IntList {
   Vector list;

   // Это конструктор
   public IntList() {
     list = new Vector();
   }

   public append(int n) {
     list.addElement(new Integer(n));
   }
}


12. Забыл привести объект к нужному типу.

Как и во всех других объектно-ориентированных языках, в Java можно
обращаться к объекту как к его суперклассу. Это называется 'upcasting',
он выполняется в Java автоматически. Однако, если переменная, поле
класса или возвращаемое значение метода объявлено как суперкласс, поля
и методы подкласса будут невидимы. Обращение к суперклассу как к подклассу
называется 'downcasting', его нужно прописывать самостоятельно (то есть
привести объект к нужному подклассу).

Студенты часто забывают о приведении оъекта к подклассу. Чаще всего это
случается при использовании массивов объектов Object и коллекций из пакета
java.util (имеется ввиду Collection Framework). В примере ниже объект String
заносится в массив, а затем извлекается из массива для сравнения с другой
строкой. Компилятор обнаружит ошибку и не станет компилировать код, пока не
будет явно указано приведение типов.

Code
Ошибочный пример.
Object arr[] = new Object[10];
arr[0] = "m"; 
arr[1] = new Character('m');

String arg = args[0];
if (arr[0].compareTo(arg) < 0) {
   System.out.println(arg + " comes before " + arr[0]);
}


Смысл приведения типов для некоторых оказывается затруднительным.
Особенно часто затруднения вызывают динамические методы. В примере выше,
если бы использовался метод equals вместо compareTo, компилятор бы не
выдал ошибку, и код бы правильно отработал, так как вызвался бы метод
equals именно класса String. Нужно понять, что динамическое связывание отличается от downcasting.

Code
Исправленный пример:
Object arr[] = new Object[10];
arr[0] = "m"; 
arr[1] = new Character('m');

String arg = args[0];
if ( ((String) arr[0]).compareTo(arg) < 0) {
   System.out.println(arg + " comes before " + arr[0]);
}




 
ProgerДата: Среда, 2006-11-08, 7:34 PM | Сообщение # 3
Administrator
Группа: Администраторы
Сообщений: 44
Репутация: 0
Статус: Offline
13. Использование интерфейсов.

Для многих студентов не совсем ясна разница между классами и интерфейсами.
Поэтому, некоторые студенты пытаются реализовать интерфейсы, такие как
Observer или Runnable, с помощью ключевого слова extends, вместо implements.
Для исправления ошибки, нужно просто исправить ключевое слово на верное.

Code
Ошибочный пример.
public class SharkSim extends Runnable {
   float length;
   ...
}

Code
Исправленный пример:
public class SharkSim implements Runnable {
   float length;
   ...
}

Связанная с этим ошибка: неправильный порядок блоков extends и implements.
Согласно спецификации Java, объявление о расширении класса должно идти
перед объявлениями о реализации интерфейсов. Также, для интерфейсов
ключевое слово implements нужно писать всего 1 раз, несколько интерфейсов
разделяются запятыми.

Code
Еще ряд ошибочных примеров:
// Неправильный порядок
public class SharkSim implements Swimmer extends Animal {
   float length;
   ...
}

// ключевое слово implements встречается несколько раз
public class DiverSim implements Swimmer implements Runnable {
   int airLeft;
   ...
}


Code
Исправленные примеры: 
// Правильный порядок
public class SharkSim extends Animal implements Swimmer {
   float length;
   ...
}

// Несколько интерфейсов разделяются запятыми
public class DiverSim implements Swimmer, Runnable {
   int airLeft;
   ...
}


14. Забыл использовать значение, возвращаемое методом суперкласса

Java позволяет вызывать из подкласса аналогичный метод суперкласса с
помощью ключевого слова keyword. Иногда студентам приходится вызывать
методы суперкласса, но при этом часто они забывают использовать
возвращаемое значение. Особенно часто это случается у тех студентов,
которые ещ не осмыслили методы и их возвращаемые значения.

В примере ниже студент хочет вставить результат метода toString()
суперкласса в результат метода toString() подкласса. При этом он не
использует возвращаемое значение метода суперкласса.

Code
Ошибочный пример.
public class GraphicalRectangle extends Rectangle {
    Color fillColor;
    boolean beveled;
    ...
    public String toString() {
      super();
      return("color=" + fillColor + ", beveled=" + beveled);
    }
}

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

Code
Исправленный пример:
public class GraphicalRectangle extends Rectangle {
    Color fillColor;
    boolean beveled;
    ...
    public String toString() {
      String rectStr = super();
      return(rectStr + " - " +
     "color=" + fillColor + ", beveled=" + beveled);
    }
}

15. Забыл добавить AWT компоненты

В AWT используется простая модель построения графического интерфейса:
каждый компонент интерфейса должен быть сначала создан с помощью своего
конструктора, а затем помещен в окно приложения с помощью метода add()
родительского компонента. Таким образом, интерфейс на AWT получает
иерархическую структуру.

Студенты иногда забывают об этих 2х шагах. Они создают компонент, но
забывают разместить его в окне приожения. Это не вызовет ошибок на этапе
компиляции, компонент просто не отобразится в окне приложения.

Code
Ошибочный пример.
public class TestFrame extends Frame implements ActionListener {
   public Button exit;

   public TestFrame() {
     super("Test Frame");
     exit = new Button("Quit");
   }
}


Чтобы исправить эту ошибку, необходимо просто добавить компоненты к
своим родителям. Пример ниже показывает, как это сделать. Необходимо
заметить, что часто студент, забывший добавить компонент в окно приложения,
также забывает назначить слушателей событий для этого компонента.

Code
Исправленный пример:
public class TestFrame extends Frame implements ActionListener {
   public Button exit;

   public TestFrame() {
     super("Test Frame");

     exit = new Button("Quit");

     Panel controlPanel = new Panel();
     controlPanel.add(exit);

     add("Center", controlPanel);

     exit.addActionListener(this);
   }

   public void actionPerformed(ActionEvent e) {
     System.exit(0);
   }
}


17. Забыл запустить поток

Многопоточность в Java реализуется с помощью класса java.lang.Thread.
Жизненный цикл потока состоит из 4х этапов: проинициализирован, запущен,
заблокирован и остановлен. ТОлько что созданный поток находится в
проинициализированном состоянии. Чтобы перевести его в запущенное
состояние, необходимо вызвать его метод start(). Иногда студенты создают
потоки, но забывают запустить их. Обычно ошибка возникает при недостаточных
знаниях студента о параллельном программировании и многопоточности. (прим.
перев.: не вижу связи) Чтобы исправить ошибку, необходимо просто запустить
поток.

В примере ниже, студент хочет создать анимацию картинки используя интерфейс
Runnable, но он забыл запустить поток.

Code
Ошибочный пример.
public class AnimCanvas extends Canvas implements Runnable {
     protected Thread myThread;
     public AnimCanvas() {
         myThread = new Thread(this);
     }

     // метод run() не будет вызван,
     // потому что поток не запущен.
     public void run() {
         for(int n = 0; n < 10000; n++) {
          try { 
           Thread.sleep(100); 
          } catch (InterruptedException e) { }
          
          animateStep(n);
         }    
     }
     ...
}


Code
Исправленный пример:
public class AnimCanvas extends Canvas implements Runnable {
     static final int LIMIT = 10000;
     protected Thread myThread;

     public AnimCanvas() {
         myThread = new Thread(this);
         myThread.start();
     }

     public void run() {
         for(int n = 0; n < LIMIT; n++) {
             try { 
              Thread.sleep(100); 
             } catch (InterruptedException e) { }

             animateStep(n);
         }
     }
     ...
}




Жизненный цикл потока и связь потоков и классов, реализующих
интерфейс Runnable - это очень важная часть программирования на Java,
и не будет лишним заострить свое внимание на этом.

18. Использование запрещенного метода readLine() класса java.io.DataInputStream

В Java версии 1.0 для считывания строки текста необходимо было
использовать метод readLine() класса java.io.DataInputStream. В Java
версии 1.1 был добавлен целый набор классов для ввода-вывода,
обеспечивающий операции ввода-вывода для текста: классы Reader и
Writer. Таким образом с версии 1.1 для чтения строки текста надо
использовать метод readLine() класса java.io.BufferedReader. Студенты
могут не знат об этом изменении, особенно если они обучались по
старым книгам. (прим. перев. вообще-то уже не актуально. вряд ли кто-то
станет сейчас учиться по книгам 10летней давности.)

Старый метод readLine() оставлен в JDK, но объявлен как запрещенный, что
часто смущает студентов. Необходимо понять, что использование метода
readLine() класса java.io.DataInputStream не является неправильным, оно
просто устарело. Необходимо использовать класс BufferedReader.

Code
Ошибочный пример.
public class LineReader {
   private DataInputStream dis;

   public LineReader(InputStream is) {
     dis = new DataInputStream(is);
   }

   public String getLine() { 
     String ret = null;

     try {
      ret = dis.readLine(); // Неправильно! Запрещено.
     } catch (IOException ie) { }

     return ret;
   }
}

 

Исправленный пример:
public class LineReader {
   private BufferedReader br;

   public LineReader(InputStream is) {
     br = new BufferedReader(new InputStreamReader(is));
   }

   public String getLine() { 
     String ret = null;

     try {
      ret = br.readLine(); 
     } catch (IOException ie) { }

     return ret;
   }
}


Есть и другие запрещенные методы в версиях, более поздних чем 1.0, но
этот встречается чаще всего.

19. Использование типа double как float

Как и в большинстве других языков, в Java поддерживаются операции
над числами с плавающей точкой (дробными числами). В Java есть 2
типа-примитива для чисел с плавающей точкой: double для чисел с
64-битной точностью по стандарту IEEE, и float, для чисел с 32-битной
точностью по стандарту IEEE. Трудность заключается в использовании
десятичных чисел, таких как 1.75, 12.9e17 или -0.00003 - компилятор
присваивает им тип double.

Java не производит приведение типов в операциях, в которых может произойти
потеря точности. Такое приведение типов должен осуществлять программист.
Например, Java не позволит присвоить значение типа int переменной типа byte
без приведения типов, как показано в примере ниже.

Code
byte byteValue1 = 17; /* неправильно! */
byte byteValue2 = (byte)19; /* правильно */

Так как дробные числа представлены типом double, и присваивание double
переменной типа float может привести к потере точности, компилятор
пожалуется на любую попытку использовать дробные числа как float. Так что
использование присваиваний, приведенных ниже, не даст классу
откомпилироваться.

Code
float realValue1 = -1.7;     /* неправильно! */
float realValue2 = (float)(-1.9); /* правильно */

Это присваивание сработало бы в C или C++, для Java все гораздо строже.
Есть 3 способа избавиться от этой ошибки.

Можно использовать тип double вместо типа float. Это наиболее простое
решение. На самом деле нет особого смысла использовать 32-битную
арифметику вместо 64-битной, разницу в скорости все равно скушает
JVM (к тому же в современных процессорах все дробные числа приводятся
к формату 80-битного регистра процессора перед любой операцией).
Единственный плюс использования float - это то, что они занимают
меньше памяти, что бывает полезно при работе с большим числом дробных
переменых.

Можно использовать модификатор для обозначения типа числа, чтобы
сообщить компилятору как хранить число. Модификатор для типа
float - 'f'. Таким образом, компилятор присвоит числу 1.75 тип double,
а 1.75f - float. Например:

Code
float realValue1 = 1.7;  /* неправильно! */
float realValue2 = 1.9f;  /* правильно */

Можно использовать явное приведение типов. Это наименее элегантный способ,
но он полезен при конвертации переменной типа double в тип float. Пример:

Code
float realValue1 = 1.7f; 
double realValue2 = 1.9;
realValue1 = (float)realValue2;


 
форум\forum » Компьютерное » Программирование » Java2 (язык програмирования java)
  • Страница 1 из 1
  • 1
Поиск:
   
Создать бесплатный сайт с uCoz