n Поскольку на момент написания программы типы и даже количество параметров неизвестно, используется другой подход:
l Ссылки на все параметры в порядке их следования помещаются в массив типа Object
l Если параметр имеет примитивный тип, то в массив помещается ссылка на экземпляр класса-оболочки соответствующего типа, содержащий необходимое значение
n Возвращается всегда тип Object
l Для ссылочного типа используется приведение типа или рефлексивное исследование
l Для примитивных типов возвращается ссылка на экземпляр класса-оболочки, содержащий возвращенное значение
Создание экземпляров классов
n Метод Object Class . newInstance ()
Возвращает ссылку на новый экземпляр класса, используется конструктор по умолчанию
n Метод
Object Constructor . newInstance ( Object [] initArgs )
Возвращает ссылку на новый экземпляр класса, с использованием конструктора и указанными параметрами конструктора
Вызов методов
n Прямой вызов
l Если на момент написания кода известен тип-предок загружаемого класса
l Приведение типа и вызов метода
n Вызов через экземпляр класса Method
Object Method.invoke(Object obj, Object[] args)
l obj – ссылка объект, у которого должен быть вызван метод
l принято передавать null, если метод статический
l args – список параметров для вызова методов
Пример вызова статического метода
import java.lang.reflect.*;
public class Main {
public static void main(String[] args) {
if (args.length == 3) {
try {
Class c = Class.forName(args[0]);
Method m = c.getMethod(args[1], new Class [] {Double.TYPE});
Double val = Double.valueOf(args[2]);
Object res = m.invoke(null, new Object [] {val});
System.out.println(res.toString());
} catch (ClassNotFoundException e) {
System . out . println ("Класс не найден");
} catch (NoSuchMethodException e) {
System.out.println(" Метод не найден ");
} catch (IllegalAccessException e) {
System.out.println(" Метод недоступен ");
} catch (InvocationTargetException e) {
System . out . println ("При вызове возникло исключение");
}
}
}}
Вопрос 81 Загрузчики классов и их возможности. 15-18 Лекция механизмы рефлексии.
Класс ClassLoader
n Экземпляры класса отвечают
за загрузку классов
в виртуальную машину
n Это абстрактный класс,
не имеющий ни одного
абстрактного метода
n Классы-наследники должны в каком-то смысле расширять возможности виртуальной машины по загрузке классов
n Объекты загрузчиков образуют иерархию (родительский объект указывается как параметр защищённых конструкторов)
Основные методы класса ClassLoader
n public Class loadClass(String name)
l Проверяет, не был ли класс загружен раньше
l Вызывает аналогичный метод родительского объекта
l Вызывает метод findClass (), чтобы найти класс
l Не стоит переопределять этот метод
n protected Class findClass(String name)
l Ищет и загружает класс по имени специфическим для данного загрузчика способом
l Этот метод и нужно переопределять
n protected final Class defineClass(
String name, byte[] b, int off, int len)
l Загружает класс из указанного набора байтов
Пример использования загрузчика классов
package reflectiontest;
import java.io.*;
public class ArbitraryFileLoader extends ClassLoader {
public Class loadClassFromFile(String filename) throws IOException {
byte[] b = loadClassData(filename);
return defineClass(null, b, 0, b.length);
}
private byte[] loadClassData(String filename) throws IOException {
FileInputStream in = new FileInputStream(filename);
byte[] fileContent = new byte[in.available()];
in.read(fileContent);
in.close();
return fileContent ;
}
}
Пример использования загрузчика классов
public class ReflectionTest {
public static void main(String[] args) {
try {
ArbitraryFileLoader l = new ArbitraryFileLoader();
Object o = l.loadClassFromFile(args[0]).newInstance();
if (o instanceof Somethingable) {
System.out.println(((Somethingable) o).something());
}
} catch (java.io.IOException ex) {
System.out.println("Problem with reading of file");
} catch (ClassFormatError ex) {
System.out.println("File doesn't contain a class");
} catch (IllegalAccessException ex) {
System.out.println("No public constructor");
} catch (InstantiationException ex) {
System.out.println("Problem during object creation");
}
}
}
Дата: 2019-07-30, просмотров: 247.