Язык программирования Java Дмитриев Андрей Владиславович Май 2007.

Презентация:



Advertisements
Похожие презентации
1 © Luxoft Training 2013 Модуль 7 Введение Исследование классов 7-1 Механизм Reflection.
Advertisements

Наследование Наследование – это отношение является между классами. class Person { string first_name; int birth_year;... } class Student : Person { float.
Основы информатики Классы Заикин Олег Сергеевич zaikin.all24.org
Синтаксис языка Java. Символы и синтаксис Перевод строчки эквивалентен пробелу Регистр в именах различается.
Полиморфизм. Полиморфизм – это свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта.
Изучение динамического определения типов. Класс Class. Динамическая загрузка и инстанцирование классов. В Java вся информация о классе хранится в специальном.
Основы ООП и C# Работа с объектами и классами. Классы Класс специальный тип данных для описания объектов. Он определяет данные и поведение типа. Определение.
Лекция 4. Введение в С++ Наследование, множественное наследование. Конструкторы, деструкторы. Виртуальные функции.
1 Java 6. ИНТЕРФЕЙСЫ И ВНУТРЕННИЕ КЛАССЫ. 2 Интерфейсы Не являются классами Ни один из объявленных методов не может быть реализован внутри интерфейса.
Идентификация типа во время выполнения RTTI. Механизм состоит из нескольких частей: Базовые средства RTTI лежат в основе механизма полиморфизма. При первом.
1 © Luxoft Training 2012 Java: расширенные вопросы Модуль #8.
Наследование Полиморфизм ВЫЗОВ КОНСТРУКТОРОВ И ДЕСТРУКТОРОВ ПРИ НАСЛЕДОВАНИИ.
Обобщения ( generics) Обобщения – это классы, структуры, интерфейсы и методы, в которых некоторые типы сами являются параметрами. Эти типы перечисляются.
Лекция 7 Классы - оболочки Каждому простому типу в Java соответствует класс-оболочка. Классы-оболочки выполняют две основные функции. Первая состоит в.
Учебный курс Объектно-ориентированный анализ и программирование Лекция 7 Методы как средство реализации операций Лекции читает кандидат технических наук.
Обработка исключительных ситуаций Исключительная ситуация (исключение) – это ошибка, возникающая во время выполнения программы. Например, ошибка работы.
Test 6 Вопрос 1. Как можно уничтожить объект в Java? a)присвоить null всем ссылкам на объект b)вызвать Runtime.getRuntime().gc() c)вызвать метод finalize()
Перегрузка операторов x = a + b результат 1-й операнд2-й операнд оператор По количеству операндов операторы делятся на: унарные (один операнд) бинарные.
1 Классы в Java Ключевое слово class означает: Я говорю тебе, как выглядит новый тип объекта. Класс является базовым элементом объектно-ориентированного.
Кафедра ОСУ, Java 2004 Слайд 1 Наследование Наследование позволяет использовать существующий класс для определения новых классов, т.е. способствует.
Транксрипт:

Язык программирования Java Дмитриев Андрей Владиславович Май 2007

Часть 9. Информация о классах во время выполнения Введение Пакет java.lang.reflect RTTI - run-time type identification

Введение Это механизм, используемый для отслеживания или изменения состояния приложения, выполняемого внутри JVM Приложение может использовать любой член любого доступного внешнего класса по его имени

Недостатки Производительность приложения, использующего рефлексию обычно ниже, чем у приложения, ее не использующего Требует соответствующего разрешения для работы Нарушение целостности кода за счет возможности обращения к методам и полям, возможно, не предназначенным для прямого изменения

Типы объектов Каждый объект это либо ссылка(и наследник Object), либо примитивный тип Для каждого типа объекта JVM создает немодифицируемый экземпляр класса java.lang.Class

Возможности java.lang.Class Предоставляет API для доступа ко всем свойствам объекта Позволяет создавать экземпляры класса

Получение экземпляра Class Object.getClass().class Class.forName() Поле TYPE класса-обертки

Получение экземпляра Class(getClass()) Class c = "foo".getClass(); byte[] bytes = new byte[1024]; Class c = bytes.getClass();

Получение экземпляра Class(.class) Class c = boolean.class; // верно Class c = java.io.PrintStream.class; Class c = int[][][].class; boolean b; Class c = b.getClass(); //ошибка компиляции

Получение экземпляра Class(forName()) Class c = Class.forName("com.console.MyButton"); Class cStringArray = Class.forName("[[Ljava.lang.String;"); Class cDoubleArray = Class.forName("[D"); Должно быть известно имя класса Нельзя применять для примитивных типов

Получение экземпляра Class(TYPE) Class c = Double.TYPE; //аналог double.class Class c = Void.TYPE;

Методы для доступа к классам Class.getSuperclass() Class c = mypack.MyButton.class.getSuperclass(); Class.getClasses() – все внутренние классы Class [] c = Character.class.getClasses(); Class.getDeclaredClasses() – все внутренние классы, описанные в текущем классе Class.getEclosingClass() – содержащий класс public class MyClass { static Object o = new Object() { public void m() {} }; static Class =o.getClass().getEnclosingClass(); }

Параметры класса(с 5.0) Class c = Class.forName(MyButton); TypeVariable[] tv = c.getTypeParameters(); Type[] intfs = c.getInterfaces(); Class ancestor = c.getSuperclass();

Доступ к членам класса Package Class.getPackage() Contructor ctors [] Class.getConstructors() Field fields[] Class.getFields() Method methods Class.getMethods() Method methods2 Class.getDeclaredMethods()

Создание объекта class Cls { private Cls() {} } Class c = Class.forName("Cls"); c.newInstance(); Вывод: java.lang.IllegalAccessException: Class TestReflect can not access a member of class Cls with modifiers "private"

java.lang.reflect.Member Field –Получение типа, модификаторов, чтение и установка значения Method –Получение типа, модификаторов, вызов Constructor –Поиск по параметрам, получение модификаторов, создание экземпляра

Field try { Class c = Class.forName(ClassName); Field f = c.getField(FieldName); System.out.println(f.getType()); System.out.println(f.isSynthetic()); System.out.println(f.getModifiers()); //для разбора использовать java.lang.reflect.Modifier } catch (ClassNotFoundException x) { } catch (NoSuchFieldException x) {}

Установка значения Class c = book.getClass(); Field chap = c.getDeclaredField("chapters"); Field chars = c.getDeclaredField("characters"); chap.setAccessible(true); //при необходимости изменять final, private Field t = c.getDeclaredField(aField"); chap.setLong(book, 111); String[] newChars = { "Queen", "King" }; chars.set(book, newChars); t.set(book, new Object());

Method Class c = Class.forName(MyClass); Method[] allMethods= c.getDeclaredMethods(); Method m = allMethods[0]; System.out.println(m.getReturnType()); Class[]pType = m.getParameterTypes(); Class[]xType = m.getExceptionTypes(); System.out.println( m.getModifiers() );

Вызов метода(1/2) Class c = Class.forName(args[0]); Object obj = c.newInstance(); m.setAccessible(true); Object result = m.invoke(obj, Hello);

Вызов метода(2/2) Class c = Class.forName(TimeTable); Class[] argTypes = new Class[] { String[].class }; Method m = c.getDeclaredMethod("main", argTypes); String[] mArgs = new String[]{one, two}; main.invoke(null, (Object)mArgs);

Constructor Class c = Class.forName(name); Constructor[] allConstructors = c.getDeclaredConstructors(); for (Constructor ctor : allConstructors){ Class[] pType = ctor.getParameterTypes(); for (int i = 0; i < pType.length; i++) { //выбор конструктора по параметрам if (pType[i].equals(seekArgs)) {…} … }

Модификаторы конструктора Class c = Class.forName(name); Constructor[] allConstructors = c.getDeclaredConstructors(); Constructor ctor = allConstructors[0]; System.out.println(ctor.getModifiers());

Создание экземпляра Class.newInstance() –Разрешен вызов только конструктора без параметров –Пробрасывает исключение, если оно возникло во время создания –Требуется видимый конструктор Constructor.newInstance() –Может вызывать скрытые конструкторы

Использование экземпляра Constructor ctor = MyClass.class.getDeclaredConstructor(Ob ject.class); ctor.setAccessible(true); MyClass mc = (MyClass)ctor.newInstance(stub); mc.printField();

Необходимость RTTI

Пример иерархии классов import java.util.*; class Shape { void draw() { System.out.println(this + ".draw()"); } class Circle extends Shape { public String toString() { return "Circle"; } } class Square extends Shape { public String toString() { return "Square"; } } class Triangle extends Shape { public String toString() { return "Triangle"; } }

Использование иерархии public class Shapes { public static void main(String[] args) { ArrayList s = new ArrayList(); s.add(new Circle()); s.add(new Square()); s.add(new Triangle()); Iterator e = s.iterator(); while(e.hasNext()) ((Shape)e.next()).draw(); }

Механизм RTTI Приведение к базовому классу происходит при добавлении e.hasNext() возвращает значение java.lang.Object Попытка приведения к типу Shape приводит к проверке приведения на корректность. Это и есть RTTI –проверка на корректность по время исполнения Проявление полиморфизма: вызов соответствующего метода классов Square, Circle и Rectangle Пока программа заинтересована только в типе Shape

Если нужно знать точный тип во время выполнения информация о типе представляется с помощью специального типа объекта Class, который содержит информацию о классе Объект Class существует для каждого класса, который является частью программы Во время компиляции класса создается объект типа Class и хранится в виде одноименного файла с расширением.class Во время выполнения при попытке создания любого объекта JVM проверяет, загружен ли объект Class этого класса. Т.о. программа не загружается полностью перед запуском

Классы, демонстрирующие момент загрузки class Candy { static { System.out.println("Loading Candy");//выполнится при загрузке } class Gum { static { System.out.println("Loading Gum"); //выполнится при загрузке }

Время загрузки классов new Candy(); //класс загружен, т.к. создан объект этого класса System.out.println("After creating Candy"); try { Class.forName("Gum"); //Один из способов получить ссылку на объект } catch(ClassNotFoundException e) { e.printStackTrace(System.err); } System.out.println("After Class.forName(\"Gum\")");

Получение объекта типа Class С помощью литералов объекта: Gum.class Этот способ безопаснее, т.к. проверка происходит во время компиляции Литералы объектов Class работают с классами, интерфейсами, массивами и примитивными типами

Доступ через класс-оболочку boolean.class Boolean.TYPE char.class Character.TYPE byte.class Byte.TYPE short.class Short.TYPE int.class Integer.TYPE long.class Long.TYPE float.class Float.TYPE double.class Double.TYPE void.class Void.TYPE

Определение типа объекта Стандартное приведение выбрасывает исключение ClassCastException при попытке произвести неправильное приведение Объект Class может быть опрошен для получения информации Оператор instanceof

Использование instanceof проверка, является ли объект obj экземпляром класса Circle перед приведением объекта obj к типу Cirlce Рекомендуется использовать instanceof перед нисходящим приведением if (obj instanceof Circle){ //вызов специфичного для класса Circle метода radius = ((Circle)obj).getRadius(); }

Сравнение классов(1) //class Base {} //class Derived extends Base {} Base base = new Base(); base.getClass() instanceof Base) //true base.getClass()instanceof Derived) //false Base.class.isInstance(base) //true Derived.class.isInstance(base) //false base.getClass() == Base.class) //true base.getClass() == Derived.class) //false base.getClass().equals(Base.class) //true base.getClass().equals(Derived.class)) //false

Сравнение классов(2) Derived derived = new Derived(); derived.getClass() instanceof Base) //true derived.getClass()instanceof Derived) //true Base.class.isInstance(derived ) //true Derived.class.isInstance(base) //true derived.getClass() == Base.class) //false derived.getClass() == Derived.class) //true derived.getClass().equals(Base.class) //false derived.getClass().equals(Derived.class)) //true

Методы класса Class getInterfaces() – возвращает массив объектов типа Class, реализованных данным классом getSuperclass() – возвращает класс предка newInstance() – создание экземпляра класса getName() – имя класса isInterface() – является ли данный класс интерфейсом

Правда ли что… Следующее присваивание не скомпилируется: Class intClass = int.class; С помощью рефлексии для доступа ко всем методам и полям всех классов необходим экземпляр класса В структуре класса есть поля и методы, явно не определенные в программе