Невозможно отобразить презентацию
Similar presentations:
Характеристики языка Java. Лекция 1
1 Характеристики языка Java Простой (нет указателей, нет освобождения памяти, нет перегрузки операций, нет шаблонов, нет множественного наследования).
Объектно-ориентированный, в Java даже нет глобальных переменных или функций, есть только поля и методы классов.
Платформо-независимый т.е.
не ориентирован на какую-то одну аппаратную или программную архитектуру.
Устойчивый (проверяет выход за границу массива, не только предоставляет аппарат исключений, но и требует от программиста их обработки).
Многопоточный, средства работы с потоками встроены в язык.
Интерпретируемый, выполнение программы происходит путем интерпретации частично откомпилированного кода.
Распределенный (позволяет выполнять удаленные вызовы методов).
Динамический (использует информацию о типах и отражение).2 Этапы программирования на языке Java Исходный код (*.java) Байт-код (*.class) Виртуальная машина Java Windows Linux MacOS FreeBSD3 Типы программ Java апплеты (applets) автономные приложения Web-приложения сервлеты серверные страницы JSP компоненты EJB Web-сервисы4 Технология Java JDBC 3.0 Security TransactionsSAXDOM AppletsAWT SwingI/O Utils JDBC SocketsRMI CORBA JNDI J2SE Core/DesktopGUI Distributed Core ServletsJSPJSFEJB ConnectorJMS JavaMailWeb Enteprise Messaging J2EE Enterprise/Server J2ME Mobile/Wireless CLDC (MIDP)CDC Java Card JAXB JAX-RPC JAXR JAXM JAXP SAAJ JWSDP Web Services5 Состав JDK6 Основные пакеты J2SE java.applet java.awt java.io java.lang java.lang.reflect java.net java.nio java.rmi java.security java.sql java.text java.util javax.swing javax.xml.parsers Классы, объекты и объектные ссылки Класс в Java – это некоторое описание типа Объект представляет собой экземпляр класса Классы и объекты обладают методами и атрибутами Доступ к объектам и вызов их методов осуществляется посредством объектных ссылок.
Ссылка может не ссылаться ни на какой объект — тогда это пустая ( null ) ссылка.
Все ссылки строго типизированы Данные простых типов ссылками не являются Атрибуты и методы Атрибуты класса определяют, из каких данных будут состоять объекты этого класса.
Атрибуты могут быть ссылками на другие объекты или простыми типами.
Методы класса определяют поведение объекта этого класса.
Методы и атрибуты могут иметь следующую область видимости: public —доступ без каких-либо ограничений;
private — доступ разрешен только из данного класса;
protected — доступ разрешен из данного класса и из всех классов-потомков, а также из всех классов данного пакета.
„default" — доступ разрешен из всех классов данного пакета.
Getters and Setters Область видимости изменяемых атрибутов класса всегда лучше делать private или protected , а для доступа к этим полям применять get- и set-методы privateint age;
publicint getAge(){ return age;
} public void setAge(int age){ this.age = age;
} Параметры методов Параметры методов передаются только по значению , поэтому изменение параметра внутри метода не влияет на оригинальную переменную При передаче ссылки на объект в качестве параметра копируется сама ссылка , поэтому переприсваивание ей другого объекта не влечет за собой изменения передаваемой ссылки.
Однако изменения полей объекта в этом случае остаются в силе.
public void someMethod(int i, String str, StringBuffer sb){ i = 10;
str = “Bye”;
sb.insert(0, “Hello, ”);}… int j = 20;
String s = “Hello”;
StringBuffer sb = new StringBuffer(“Viktor”);
someMethod(j, s, sb);
Конструкторы Конструктор – это специальный метод класса, который вызывается при создании объекта.
Конструктор без параметров называется конструктором по умолчанию (default constructor).
Если в классе нет ни одного конструктора, то генерируется пустой конструктор по умолчанию.
Если в классе есть хотя бы один конструктор, то конструктор по умолчанию не генерируется.
Если у родителя текущего класса есть конструктор без параметров, он вызывается перед вызовом конструктора дочернего класса автоматически.
Если у родителя задан лишь конструктор с параметрами – он может быть вызван только в начале конструктора дочернего класса public SomeClass(parentArgs, newArgs){ super(parentArgs);…} protected конструктор может быть вызван: при помощи оператора new или метода super() из класса в том же пакете;
из потомка класса только при помощи метода super package x;
public class A { protected A() { System.out.println("Hello");
}} package X;
public class B { public B() { A a = new A();
}} package y;
public class C extends x.A { public C() { super();
x.A a = new x.A();
}} private-конструктор Для класса только с одним private- конструктором справедливы утверждения: экземпляры класса могут быть созданы только внутри этого класса.
этот класс не может быть унаследован (исключения составляют вложенные классы).
Singleton Pattern public class DBConnection { private static DBConnection singleton=null;
private DBConnection() { //do something} public static DBConnection getInstance() { if(singleton = = null) singleton = new DBConnection();
return singleton;} IШаблон Singleton используется, когда необходимо обеспечить существование только одного экземпляра данного класса Модификатор доступа final Применительно к полям, переменным и параметрам он запрещает их изменение.
В этих случаях компилятор выдаст ошибку: константы обычно объявляются как static final public static final double PI = 3.14;
Внимание: в случае применения модификатора final при описании объектных ссылок неизменной будет только сама ссылка .
Однако это не значит, что поля объекта не будут изменяемыми.
static finalint [] mas = {1, 2, 3};
mas[2] = 100;
// допустимо – меняется поле объекта mas =newint []{5, 6, 7};
// недопустимо – меняется ссылка на объект final-метод не может быть переопределен в наследниках классa final-класс не может быть унаследован public int getVal(final int i) { return ++i;
} finalint maxVal = 100;
maxVal = 1000;
Статические методы и атрибуты В Java есть статические атрибуты и статические методы.
Для атрибута описатель static означает, что: такое поле создается в единственном экземпляре вне зависимости от количества объектов данного класса.
статическое поле существует даже в том случае, если не создано ни одного экземпляра класса.
атрибут размещается VM Java отдельно от объектов класса в некоторой области памятив момент первого обращения к данному классу Демонстрация работы со статическим атрибутом public class Counter { private static int cnt = 0;
// статическое поле public Counter(){ cnt++;
// Увеличивает значение cnt при создании // каждого нового объекта этого класса } public static void main(String args[]) { Counter с1 = new Counter();// cnt будет равно 1 Counter с2 = new Counter();// cnt будет равно 2 System.out.println(cnt);
// Распечатывает cnt }} Особенности статических методов Статические методы не привязаны к конкретному объекту класса При вызове статического метода перед ним можно указать не ссылку, а имя класса class SomeClass { public static void f() { // статический метод }}… SomeClass.f();… Внутри статического метода нельзя обращаться к нестатическим полям класса без указания объекта перед именем поля.
Статический метод генерации Статический метод генерации возвращает экземпляр класса Статические методы генерации, в отличие от конструкторов, имеют название Они не обязаны при каждом вызове создавать новый объект public static Boolean valueOf(boolean b){ return (b? Boolean.TRUE : Boolean.FALSE);} Они могут вернуть не только экземпляр заявленного типа, но и его подтипа Блок static{…} Блок static{…} применяется, как правило, для инициализации статических атрибутов, если это нельзя сделать при объявлении поля.
Код в этом блоке выполняется один раз при первом обращении к классу public class Auto{ public static final Map AUTOS = new HashMap();… static{ AUTOS.put(“M”, new Auto(“Mercedes”));
AUTOS.put(“B”, new Auto(“BMW”));}…} Auto.AUTOS.get(“M”) // Вернет ссылку на объект-Мерседес.
Наследование классов Наследование позволяет строить новые классы на базе существующих, добавляя в них новые возможности или переопределяя существующие.
В Java нет множественного наследования На объекты дочернего класса можно ссылаться по ссылке родительского класса( downcasting) Shape +coords: Point +area (): double Rectangle+xy : int +<<Override>>area (): double Circle +radius: int +<<Override>>area (): double Shape rect = new Rectangle();
rect.area();
Абстрактные классы Абстрактный класс - это класс, от которого ведут наследование другие классы, а объектов этого класса не существует.
Абстрактный класс объявляется с помощью ключевого слова abstract.
Абстрактный класс может содержать нереализованные (абстрактные) методы.
Это значит, что они должны быть реализованы наследниками этого класса.
Интерфейсы Интерфейс — класс, в котором все методы являются public и abstract Поля интерфейса по умолчанию являются final, public и static.
Данные модификаторы допускается не указывать Один класс может реализовывать несколько интерфейсов.
public interface D { int k = 0;
int getK();} public class C implements D { public int getK() { return D.k++;
} Вложенные классы Описание вложенного класса находится внутри фигурных скобок тела другого класса Вложенный класс может быть помещен на уровень описания охватывающего класса, внутрь некоторого метода охватывающего класса, а также внутрь некоторого блока При порождении объекта inner-класса из охватывающего класса синтаксис обычный: Inner1 i1 = new Inner1();
При порождении объекта inner-класса извне охватывающего класса нужно чтобы inner-класс был доступен извне и, кроме того, чтобы существовал объект охватывающего класса.
Outer.Inner1 i2 = t1.new Inner1();
Внутренние классы имеют ссылку на охватывающий класс.
Из них возможен доступ к полям охватывающего класса.
Пример вложенного класса public class Outer { private int val = 100;
class Inner { private int val = Outer.this.val;
public Inner() { Outer.this.val = 5000;
} private void printVal() { System.out.println(val);
System.out.println(Outer.this.val);
} } public static void main(String args[]) { Outer.Inner in = new Outer().new Inner();
in.printVal();
}} Анонимные классы Анонимные классы — это классы без имени Они являются подмножеством вложенных классов Описание анонимного класса и создание объекта производится одновременно – это позволяет сократить код class A{ void doSome(){…} // Объявление метода doSome в A}… A newA = new A{ void doSome(){ // Переопределение метода doSome … someOther … // код новой бизнес-логики} Статические вложенные классы Статические вложенные классы используются тогда, когда из вложенного класса требуется обращаться только к статическим полям и методам охватывающего класса При порождении объекта статического inner-класса не нужен объект охватывающего класса При порождении объекта статического inner-класса из охватывающего класса синтаксис обычный: Inner inn = new Inner();
При порождении объекта статического inner-класса извне перед именем внутреннего класса нужно указывать имя охватывающего класса.
Однако, если у вас возникает необходимость это делать – возможно, следует отказаться от использования внутреннего класса.
Outer.Inner inn = new Outer.Inner();
Класс Object Object – базовый класс в Java.
От него наследуются все остальные классы Некоторые методы класса Object: clone() - создает и возвращает копию этого объекта.
equals(Object obj) – указывает на то, что этот объект в некотором смысле равен другому.
finalize() – вызывается сборщиком мусора перед удалением объекта hashCode() – возвращает хеш-код объекта.
toString() – возвращает строковое представление объекта Метод boolean equals(Object obj) Метод equals следует переопределять тогда, когда для класса существует понятие логической эквивалентности, которое не совпадает с тождественностью объектов Метод equals должен удовлетворять следующим требованиям: Рефлексивность .
x.equals(x) всегда должно быть true.
Симметричность .
Если x.equals(y) == true, то и y.equals(x) должно быть true Транзитивность .
Если x.equals(y) == true, y.equals(z) == true то и x.equals(z) должно быть true Непротиворечивость.
x.equals(null) всегда должно возвращать false.
Метод equals(Object obj).
Пример public class Point { private final int x;
private final int y;
public Point(int x, int y){ this.x = x;
this.y = y;
} public boolean equals(Object obj){ if (!(obj instanceof Point)) return false;
Point p = (Point)obj;
return p.x == x && p.y == y;
}} Метод hashCode() Метод int hashCode() применяется при построении хеш-таблиц (HashSet, HashMap, и др.) Требования к методу: Он должен быть переопределен в каждом классе, где переопределен метод equals() При нескольких обращениях к объекту метод должен возвращать одно и то же число Если два объекта равны по результатам метода equals(), их хеш-коды тоже должны быть равны Если два объекта не равны по equals(), они не обязательно должны иметь одинаковых хеш-код.
Но это желательно.
public int hashCode(){ int result = 17;
result = 37*result + areaCode;
result = 37*result + extension;
return result;} Метод toString() Метод toString() возвращает строковое представление объекта Желательно, чтобы все классы переопределяли этот метод В классе Object он формирует строку как getClass().getName() + '@' + Integer.toHexString(hashCode()).
Этот метод вызывается при конкатенации строк, если указывается ссылка на объект, а также при печати объекта на консоль public class Point{ private int x, y;… public String toString(){ return “(“ + x + “, ” + y + “)”;} public static void main(String[] args){ System.out.println(new Point(1, 3)) // Распечатает (1, 3) String str = “Point ” + new Point(2, 3);
// будет равно Point (2, 3)} Метод finalize() Метод finalize() вызывается сборщиком мусора непосредственно перед удалением объекта Как правило, используется для освобождения ресурсов, используемых объектом.
Он не должен содержать никаких критических по времени операций, поскольку время удаления объекта не регламентировано На практике вместо того, чтобы помещать всю логику по освобождению ресурсов в этот метод, используйте метод прямого завершения (пример - метод close() у java.io.OutputStream).
Метод finalize() следует применять только в качестве запасного варианта для освобождения ресурсов (проверять, был ли вызван метод прямого завершения, и если нет – вызывать его).
Исключения Исключительная ситуация - это проблема, мешающая последовательному исполнению метода или ограниченного участка кода, решение которой в данном контексте невозможно.
Исключения используются для досрочного окончания выполнения участка кода и передачи управления на верхний уровень.
При возникновении исключения порождается объект, связанный с данным исключением.
Этот объект служит для хранения информации о возникшей исключительной ситуации (точка возникновения, описание и т.п.).
Виды исключений Throwable — базовый класс для всех исключительных ситуаций.
Error — базовый класс для исключительных ситуаций, вызванных серъезными сбоями в работе виртуальной машины Java.
Exception — это базовый класс для всех тех исключений, с которыми мы имеем дело в программах.
RuntimeException – ошибка времени выполнения.
Ее обработка не обязательна.
Генерация исключений Два варианта генерации исключений – автоматическая и программная.
Автоматическая генерация исключения производится, если Java-машина обнаруживает некоторую ошибку, например, деление на ноль, ошибку приведения типов или обращение к полям и методам объекта по объектной ссылке, значение которой null.
“abc”.equals(str) // Такой вариант сравнения строк безопасен, поскольку при str == null выражение вернет false str.equals(“abc”) // при использовании такого варианта если str == null возникнет NullPointerException.
Программная генерация исключений Программная генерация производится с помощью оператора throw: thrownew IllegalArgumentException("Параметр age должен быть положительным числом");
При этом, если исключение не обрабатывается в данном методе, в описании метода должна стоять директива throws.
public InputStream getFileStream() throws IOException{ return new FileInputStream(“dummy.txt”);} Обработка исключений Сгенерированная исключительная ситуация должна быть соответствующим образом обработана.
В противном случае программа будет досрочно завершена.
Для этих целей используется конструкцияtry{…} catch (SomeException1 e){…} catch (SomeException2 e){…} finally{…} Пример обработки исключенийtry { inputFile("data.txt");
calculate();} catch (FileNotFoundException e) { System.out.println("Файл data.txt не найден");} catch (IOException e) { System.out.println(e.getMessage());} catch (ArithmeticException e) { e.printStackTrace();
// Распечатывает в стандартный поток // информацию о точке возникновения исключения} Создание собственного исключения public class MyException extends Exception { public MyException() {};
public MyException(String msg) { super(msg);
};} Следует отметить, что в данном случае создано исключение обязательное к перехвату.
Если нужно создать исключение, которое не обязательно перехватывать, то нужно унаследовать его от RuntimeException.
Стандартные исключения времени выполнения IllegalArgumentException Неправильное значение параметра IllegalStateException Состояние объекта неприемлемо для вызова метода NullPointerException Значение параметра равно null, а это запрещено IndexOfBoundsException Значение параметра, задающего индекс, выходит за границы диапазона ConcurrentModificationException Обнаружена параллельная модификация объекта из разных потоков, а это запрещено UnsupportedOperationException Объект не имеет поддержки указанного метода Используйте исключения лишь в исключительных ситуациях Никогда не делайте так: try{ int i= 0;
while(true) a[i++].f();
}catch(ArrayIndexOfBoundsException e){} Правильно так: for (int i = 0;
i < a.length;
i++){ a[i].f();} Избегайте ненужных обрабатываемых исключений Вызов с обрабатываемым исключениемtry{ obj.actions(args);} catch (TheCheckedException e){…} Вызов с использованием метода проверкиif (obj.actionPermitted(args)){ obj.doAction(args);} else{…} Инициируйте исключения, соответствующие абстракции public void save() throws SavingException{try{ saveToDb();
// может инициировать SQLException saveToFile();
// может инициировать IOException sendByEmail();
// может инициировать // MessagingException} catch (Exception e){ e.printStackTrace();
thrownew SavingException(e);} Не игнорируйте исключений Плохой пример – в случае возникновения исключения часть коде не выполнится, а мы этого и не заметимtry{…} catch (Exception e){} Блок catch обязан содержать, по крайней мере, комментарий, объясняющий, почему данное исключение следует игнорировать.
В описание исключения добавляйте информацию о причине его возникновения public void savePerson(String name, int age) throws SQLException{ if (age < 0 && age > 200){ throw new IllegalArgumentException(“Incorrect value for age ” + age);} if (name == null && “”.equals(name)){ throw new IllegalArgumentException(“Name must not be empty”);}…} Соглашения об именовании Имена классов должны всегда начинаться с большой буквы (например, ConnectionFactory) Имена пакетов должны состоять только из букв в нижнем регистре и цифр.
При этом каждая составляющая имени должна начинаться с буквы (например, org.apache.log4j).
Обычно имена пакетов начинаются с инвертированного имени домена компании-разработчика.
Так из приведенного выше примера видно, что разработчиком проекта log4j является Apache Software Foundation ( www.apache.org).
Названия методов и переменных должны начинаться с маленькой буквы и быть осмысленными.
Каждое новое слово должно начинаться с большой буквы.
Подчеркивания отсутствуют.
(например, insertToDatabase(), value, personName).
Названия констант состоят из больших букв, цифр и знаков подчеркивания в качестве разделителей между словами( MAX_INTEGER).
Документирование Каждый класс должен содержать Javadoc -комментарий, состоящий из краткого описания, для чего предназначен этот класс, и что он делает.
Также может быть указан автор класса с помощью директивы @author, версия (@version) /*** Этот класс предназначен для хранения информации и сотрудниках ** @author Vasya Pupkin*/ public class Employee{...} Каждый метод должен содержать комментарий с указанием того, для чего предназначен этот метод, и что он делает.
Также должны быть описаны все параметры метода и их типы, возвращаемые значения и исключения, возбуждаемые методом.
/** Рисует картинку в области с координатами (x, y).
* Метод возвращает управление сразу же, независимо о того, * успела ли полностью прорисоваться картинка.
* @param img картинка для рисования * @param x x-координата левого верхнего угла * @param y x-координата левого верхнего угла * @return <code>true</code> если картинка полностью прорисована * <code>false</code> в противном случае.
* @throws DrawingException если возникает ошибка при прорисовке картинки
Объектно-ориентированный, в Java даже нет глобальных переменных или функций, есть только поля и методы классов.
Платформо-независимый т.е.
не ориентирован на какую-то одну аппаратную или программную архитектуру.
Устойчивый (проверяет выход за границу массива, не только предоставляет аппарат исключений, но и требует от программиста их обработки).
Многопоточный, средства работы с потоками встроены в язык.
Интерпретируемый, выполнение программы происходит путем интерпретации частично откомпилированного кода.
Распределенный (позволяет выполнять удаленные вызовы методов).
Динамический (использует информацию о типах и отражение).2 Этапы программирования на языке Java Исходный код (*.java) Байт-код (*.class) Виртуальная машина Java Windows Linux MacOS FreeBSD3 Типы программ Java апплеты (applets) автономные приложения Web-приложения сервлеты серверные страницы JSP компоненты EJB Web-сервисы4 Технология Java JDBC 3.0 Security TransactionsSAXDOM AppletsAWT SwingI/O Utils JDBC SocketsRMI CORBA JNDI J2SE Core/DesktopGUI Distributed Core ServletsJSPJSFEJB ConnectorJMS JavaMailWeb Enteprise Messaging J2EE Enterprise/Server J2ME Mobile/Wireless CLDC (MIDP)CDC Java Card JAXB JAX-RPC JAXR JAXM JAXP SAAJ JWSDP Web Services5 Состав JDK6 Основные пакеты J2SE java.applet java.awt java.io java.lang java.lang.reflect java.net java.nio java.rmi java.security java.sql java.text java.util javax.swing javax.xml.parsers Классы, объекты и объектные ссылки Класс в Java – это некоторое описание типа Объект представляет собой экземпляр класса Классы и объекты обладают методами и атрибутами Доступ к объектам и вызов их методов осуществляется посредством объектных ссылок.
Ссылка может не ссылаться ни на какой объект — тогда это пустая ( null ) ссылка.
Все ссылки строго типизированы Данные простых типов ссылками не являются Атрибуты и методы Атрибуты класса определяют, из каких данных будут состоять объекты этого класса.
Атрибуты могут быть ссылками на другие объекты или простыми типами.
Методы класса определяют поведение объекта этого класса.
Методы и атрибуты могут иметь следующую область видимости: public —доступ без каких-либо ограничений;
private — доступ разрешен только из данного класса;
protected — доступ разрешен из данного класса и из всех классов-потомков, а также из всех классов данного пакета.
„default" — доступ разрешен из всех классов данного пакета.
Getters and Setters Область видимости изменяемых атрибутов класса всегда лучше делать private или protected , а для доступа к этим полям применять get- и set-методы privateint age;
publicint getAge(){ return age;
} public void setAge(int age){ this.age = age;
} Параметры методов Параметры методов передаются только по значению , поэтому изменение параметра внутри метода не влияет на оригинальную переменную При передаче ссылки на объект в качестве параметра копируется сама ссылка , поэтому переприсваивание ей другого объекта не влечет за собой изменения передаваемой ссылки.
Однако изменения полей объекта в этом случае остаются в силе.
public void someMethod(int i, String str, StringBuffer sb){ i = 10;
str = “Bye”;
sb.insert(0, “Hello, ”);}… int j = 20;
String s = “Hello”;
StringBuffer sb = new StringBuffer(“Viktor”);
someMethod(j, s, sb);
Конструкторы Конструктор – это специальный метод класса, который вызывается при создании объекта.
Конструктор без параметров называется конструктором по умолчанию (default constructor).
Если в классе нет ни одного конструктора, то генерируется пустой конструктор по умолчанию.
Если в классе есть хотя бы один конструктор, то конструктор по умолчанию не генерируется.
Если у родителя текущего класса есть конструктор без параметров, он вызывается перед вызовом конструктора дочернего класса автоматически.
Если у родителя задан лишь конструктор с параметрами – он может быть вызван только в начале конструктора дочернего класса public SomeClass(parentArgs, newArgs){ super(parentArgs);…} protected конструктор может быть вызван: при помощи оператора new или метода super() из класса в том же пакете;
из потомка класса только при помощи метода super package x;
public class A { protected A() { System.out.println("Hello");
}} package X;
public class B { public B() { A a = new A();
}} package y;
public class C extends x.A { public C() { super();
x.A a = new x.A();
}} private-конструктор Для класса только с одним private- конструктором справедливы утверждения: экземпляры класса могут быть созданы только внутри этого класса.
этот класс не может быть унаследован (исключения составляют вложенные классы).
Singleton Pattern public class DBConnection { private static DBConnection singleton=null;
private DBConnection() { //do something} public static DBConnection getInstance() { if(singleton = = null) singleton = new DBConnection();
return singleton;} IШаблон Singleton используется, когда необходимо обеспечить существование только одного экземпляра данного класса Модификатор доступа final Применительно к полям, переменным и параметрам он запрещает их изменение.
В этих случаях компилятор выдаст ошибку: константы обычно объявляются как static final public static final double PI = 3.14;
Внимание: в случае применения модификатора final при описании объектных ссылок неизменной будет только сама ссылка .
Однако это не значит, что поля объекта не будут изменяемыми.
static finalint [] mas = {1, 2, 3};
mas[2] = 100;
// допустимо – меняется поле объекта mas =newint []{5, 6, 7};
// недопустимо – меняется ссылка на объект final-метод не может быть переопределен в наследниках классa final-класс не может быть унаследован public int getVal(final int i) { return ++i;
} finalint maxVal = 100;
maxVal = 1000;
Статические методы и атрибуты В Java есть статические атрибуты и статические методы.
Для атрибута описатель static означает, что: такое поле создается в единственном экземпляре вне зависимости от количества объектов данного класса.
статическое поле существует даже в том случае, если не создано ни одного экземпляра класса.
атрибут размещается VM Java отдельно от объектов класса в некоторой области памятив момент первого обращения к данному классу Демонстрация работы со статическим атрибутом public class Counter { private static int cnt = 0;
// статическое поле public Counter(){ cnt++;
// Увеличивает значение cnt при создании // каждого нового объекта этого класса } public static void main(String args[]) { Counter с1 = new Counter();// cnt будет равно 1 Counter с2 = new Counter();// cnt будет равно 2 System.out.println(cnt);
// Распечатывает cnt }} Особенности статических методов Статические методы не привязаны к конкретному объекту класса При вызове статического метода перед ним можно указать не ссылку, а имя класса class SomeClass { public static void f() { // статический метод }}… SomeClass.f();… Внутри статического метода нельзя обращаться к нестатическим полям класса без указания объекта перед именем поля.
Статический метод генерации Статический метод генерации возвращает экземпляр класса Статические методы генерации, в отличие от конструкторов, имеют название Они не обязаны при каждом вызове создавать новый объект public static Boolean valueOf(boolean b){ return (b? Boolean.TRUE : Boolean.FALSE);} Они могут вернуть не только экземпляр заявленного типа, но и его подтипа Блок static{…} Блок static{…} применяется, как правило, для инициализации статических атрибутов, если это нельзя сделать при объявлении поля.
Код в этом блоке выполняется один раз при первом обращении к классу public class Auto{ public static final Map AUTOS = new HashMap();… static{ AUTOS.put(“M”, new Auto(“Mercedes”));
AUTOS.put(“B”, new Auto(“BMW”));}…} Auto.AUTOS.get(“M”) // Вернет ссылку на объект-Мерседес.
Наследование классов Наследование позволяет строить новые классы на базе существующих, добавляя в них новые возможности или переопределяя существующие.
В Java нет множественного наследования На объекты дочернего класса можно ссылаться по ссылке родительского класса( downcasting) Shape +coords: Point +area (): double Rectangle+xy : int +<<Override>>area (): double Circle +radius: int +<<Override>>area (): double Shape rect = new Rectangle();
rect.area();
Абстрактные классы Абстрактный класс - это класс, от которого ведут наследование другие классы, а объектов этого класса не существует.
Абстрактный класс объявляется с помощью ключевого слова abstract.
Абстрактный класс может содержать нереализованные (абстрактные) методы.
Это значит, что они должны быть реализованы наследниками этого класса.
Интерфейсы Интерфейс — класс, в котором все методы являются public и abstract Поля интерфейса по умолчанию являются final, public и static.
Данные модификаторы допускается не указывать Один класс может реализовывать несколько интерфейсов.
public interface D { int k = 0;
int getK();} public class C implements D { public int getK() { return D.k++;
} Вложенные классы Описание вложенного класса находится внутри фигурных скобок тела другого класса Вложенный класс может быть помещен на уровень описания охватывающего класса, внутрь некоторого метода охватывающего класса, а также внутрь некоторого блока При порождении объекта inner-класса из охватывающего класса синтаксис обычный: Inner1 i1 = new Inner1();
При порождении объекта inner-класса извне охватывающего класса нужно чтобы inner-класс был доступен извне и, кроме того, чтобы существовал объект охватывающего класса.
Outer.Inner1 i2 = t1.new Inner1();
Внутренние классы имеют ссылку на охватывающий класс.
Из них возможен доступ к полям охватывающего класса.
Пример вложенного класса public class Outer { private int val = 100;
class Inner { private int val = Outer.this.val;
public Inner() { Outer.this.val = 5000;
} private void printVal() { System.out.println(val);
System.out.println(Outer.this.val);
} } public static void main(String args[]) { Outer.Inner in = new Outer().new Inner();
in.printVal();
}} Анонимные классы Анонимные классы — это классы без имени Они являются подмножеством вложенных классов Описание анонимного класса и создание объекта производится одновременно – это позволяет сократить код class A{ void doSome(){…} // Объявление метода doSome в A}… A newA = new A{ void doSome(){ // Переопределение метода doSome … someOther … // код новой бизнес-логики} Статические вложенные классы Статические вложенные классы используются тогда, когда из вложенного класса требуется обращаться только к статическим полям и методам охватывающего класса При порождении объекта статического inner-класса не нужен объект охватывающего класса При порождении объекта статического inner-класса из охватывающего класса синтаксис обычный: Inner inn = new Inner();
При порождении объекта статического inner-класса извне перед именем внутреннего класса нужно указывать имя охватывающего класса.
Однако, если у вас возникает необходимость это делать – возможно, следует отказаться от использования внутреннего класса.
Outer.Inner inn = new Outer.Inner();
Класс Object Object – базовый класс в Java.
От него наследуются все остальные классы Некоторые методы класса Object: clone() - создает и возвращает копию этого объекта.
equals(Object obj) – указывает на то, что этот объект в некотором смысле равен другому.
finalize() – вызывается сборщиком мусора перед удалением объекта hashCode() – возвращает хеш-код объекта.
toString() – возвращает строковое представление объекта Метод boolean equals(Object obj) Метод equals следует переопределять тогда, когда для класса существует понятие логической эквивалентности, которое не совпадает с тождественностью объектов Метод equals должен удовлетворять следующим требованиям: Рефлексивность .
x.equals(x) всегда должно быть true.
Симметричность .
Если x.equals(y) == true, то и y.equals(x) должно быть true Транзитивность .
Если x.equals(y) == true, y.equals(z) == true то и x.equals(z) должно быть true Непротиворечивость.
x.equals(null) всегда должно возвращать false.
Метод equals(Object obj).
Пример public class Point { private final int x;
private final int y;
public Point(int x, int y){ this.x = x;
this.y = y;
} public boolean equals(Object obj){ if (!(obj instanceof Point)) return false;
Point p = (Point)obj;
return p.x == x && p.y == y;
}} Метод hashCode() Метод int hashCode() применяется при построении хеш-таблиц (HashSet, HashMap, и др.) Требования к методу: Он должен быть переопределен в каждом классе, где переопределен метод equals() При нескольких обращениях к объекту метод должен возвращать одно и то же число Если два объекта равны по результатам метода equals(), их хеш-коды тоже должны быть равны Если два объекта не равны по equals(), они не обязательно должны иметь одинаковых хеш-код.
Но это желательно.
public int hashCode(){ int result = 17;
result = 37*result + areaCode;
result = 37*result + extension;
return result;} Метод toString() Метод toString() возвращает строковое представление объекта Желательно, чтобы все классы переопределяли этот метод В классе Object он формирует строку как getClass().getName() + '@' + Integer.toHexString(hashCode()).
Этот метод вызывается при конкатенации строк, если указывается ссылка на объект, а также при печати объекта на консоль public class Point{ private int x, y;… public String toString(){ return “(“ + x + “, ” + y + “)”;} public static void main(String[] args){ System.out.println(new Point(1, 3)) // Распечатает (1, 3) String str = “Point ” + new Point(2, 3);
// будет равно Point (2, 3)} Метод finalize() Метод finalize() вызывается сборщиком мусора непосредственно перед удалением объекта Как правило, используется для освобождения ресурсов, используемых объектом.
Он не должен содержать никаких критических по времени операций, поскольку время удаления объекта не регламентировано На практике вместо того, чтобы помещать всю логику по освобождению ресурсов в этот метод, используйте метод прямого завершения (пример - метод close() у java.io.OutputStream).
Метод finalize() следует применять только в качестве запасного варианта для освобождения ресурсов (проверять, был ли вызван метод прямого завершения, и если нет – вызывать его).
Исключения Исключительная ситуация - это проблема, мешающая последовательному исполнению метода или ограниченного участка кода, решение которой в данном контексте невозможно.
Исключения используются для досрочного окончания выполнения участка кода и передачи управления на верхний уровень.
При возникновении исключения порождается объект, связанный с данным исключением.
Этот объект служит для хранения информации о возникшей исключительной ситуации (точка возникновения, описание и т.п.).
Виды исключений Throwable — базовый класс для всех исключительных ситуаций.
Error — базовый класс для исключительных ситуаций, вызванных серъезными сбоями в работе виртуальной машины Java.
Exception — это базовый класс для всех тех исключений, с которыми мы имеем дело в программах.
RuntimeException – ошибка времени выполнения.
Ее обработка не обязательна.
Генерация исключений Два варианта генерации исключений – автоматическая и программная.
Автоматическая генерация исключения производится, если Java-машина обнаруживает некоторую ошибку, например, деление на ноль, ошибку приведения типов или обращение к полям и методам объекта по объектной ссылке, значение которой null.
“abc”.equals(str) // Такой вариант сравнения строк безопасен, поскольку при str == null выражение вернет false str.equals(“abc”) // при использовании такого варианта если str == null возникнет NullPointerException.
Программная генерация исключений Программная генерация производится с помощью оператора throw: thrownew IllegalArgumentException("Параметр age должен быть положительным числом");
При этом, если исключение не обрабатывается в данном методе, в описании метода должна стоять директива throws.
public InputStream getFileStream() throws IOException{ return new FileInputStream(“dummy.txt”);} Обработка исключений Сгенерированная исключительная ситуация должна быть соответствующим образом обработана.
В противном случае программа будет досрочно завершена.
Для этих целей используется конструкцияtry{…} catch (SomeException1 e){…} catch (SomeException2 e){…} finally{…} Пример обработки исключенийtry { inputFile("data.txt");
calculate();} catch (FileNotFoundException e) { System.out.println("Файл data.txt не найден");} catch (IOException e) { System.out.println(e.getMessage());} catch (ArithmeticException e) { e.printStackTrace();
// Распечатывает в стандартный поток // информацию о точке возникновения исключения} Создание собственного исключения public class MyException extends Exception { public MyException() {};
public MyException(String msg) { super(msg);
};} Следует отметить, что в данном случае создано исключение обязательное к перехвату.
Если нужно создать исключение, которое не обязательно перехватывать, то нужно унаследовать его от RuntimeException.
Стандартные исключения времени выполнения IllegalArgumentException Неправильное значение параметра IllegalStateException Состояние объекта неприемлемо для вызова метода NullPointerException Значение параметра равно null, а это запрещено IndexOfBoundsException Значение параметра, задающего индекс, выходит за границы диапазона ConcurrentModificationException Обнаружена параллельная модификация объекта из разных потоков, а это запрещено UnsupportedOperationException Объект не имеет поддержки указанного метода Используйте исключения лишь в исключительных ситуациях Никогда не делайте так: try{ int i= 0;
while(true) a[i++].f();
}catch(ArrayIndexOfBoundsException e){} Правильно так: for (int i = 0;
i < a.length;
i++){ a[i].f();} Избегайте ненужных обрабатываемых исключений Вызов с обрабатываемым исключениемtry{ obj.actions(args);} catch (TheCheckedException e){…} Вызов с использованием метода проверкиif (obj.actionPermitted(args)){ obj.doAction(args);} else{…} Инициируйте исключения, соответствующие абстракции public void save() throws SavingException{try{ saveToDb();
// может инициировать SQLException saveToFile();
// может инициировать IOException sendByEmail();
// может инициировать // MessagingException} catch (Exception e){ e.printStackTrace();
thrownew SavingException(e);} Не игнорируйте исключений Плохой пример – в случае возникновения исключения часть коде не выполнится, а мы этого и не заметимtry{…} catch (Exception e){} Блок catch обязан содержать, по крайней мере, комментарий, объясняющий, почему данное исключение следует игнорировать.
В описание исключения добавляйте информацию о причине его возникновения public void savePerson(String name, int age) throws SQLException{ if (age < 0 && age > 200){ throw new IllegalArgumentException(“Incorrect value for age ” + age);} if (name == null && “”.equals(name)){ throw new IllegalArgumentException(“Name must not be empty”);}…} Соглашения об именовании Имена классов должны всегда начинаться с большой буквы (например, ConnectionFactory) Имена пакетов должны состоять только из букв в нижнем регистре и цифр.
При этом каждая составляющая имени должна начинаться с буквы (например, org.apache.log4j).
Обычно имена пакетов начинаются с инвертированного имени домена компании-разработчика.
Так из приведенного выше примера видно, что разработчиком проекта log4j является Apache Software Foundation ( www.apache.org).
Названия методов и переменных должны начинаться с маленькой буквы и быть осмысленными.
Каждое новое слово должно начинаться с большой буквы.
Подчеркивания отсутствуют.
(например, insertToDatabase(), value, personName).
Названия констант состоят из больших букв, цифр и знаков подчеркивания в качестве разделителей между словами( MAX_INTEGER).
Документирование Каждый класс должен содержать Javadoc -комментарий, состоящий из краткого описания, для чего предназначен этот класс, и что он делает.
Также может быть указан автор класса с помощью директивы @author, версия (@version) /*** Этот класс предназначен для хранения информации и сотрудниках ** @author Vasya Pupkin*/ public class Employee{...} Каждый метод должен содержать комментарий с указанием того, для чего предназначен этот метод, и что он делает.
Также должны быть описаны все параметры метода и их типы, возвращаемые значения и исключения, возбуждаемые методом.
/** Рисует картинку в области с координатами (x, y).
* Метод возвращает управление сразу же, независимо о того, * успела ли полностью прорисоваться картинка.
* @param img картинка для рисования * @param x x-координата левого верхнего угла * @param y x-координата левого верхнего угла * @return <code>true</code> если картинка полностью прорисована * <code>false</code> в противном случае.
* @throws DrawingException если возникает ошибка при прорисовке картинки
programming