Механизм отражения JAVA находится в запущенном состоянии, для любого класса (файла класса) можно знать все свойства и методы этого класса, для любого объекта можно вызывать любые его методы и свойства, это динамическое получение информации и функция динамического вызова методов объекта называется механизмом отражения языка java. Динамически получать информацию в классе, то есть отражение Java. Можно понимать как анатомию класса. Чтобы разобрать файл байт-кода, требуется объект файла байт-кода.
Как получить объект файла байт-кода?
Пример: создайте пакет bean-компонента и создайте новый класс Person в пакете.
package bean;
public class Person {
private int age;
private String name;
public Person(String name,int age) {
super();
this.age = age;
this.name = name;
System.out.println("Person param run..."+this.name+":"+this.age);
}
public Person() {
super();
System.out.println("person run");
}
public void show(){
System.out.println(name+"...show run..."+age);
}
private void privateMethod(){
System.out.println(" method run ");
}
public void paramMethod(String str,int num){
System.out.println("paramMethod run....."+str+":"+num);
}
public static void staticMethod(){
System.out.println(" static method run......");
}
}
package Test28;
import bean.Person;
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub
GetClassObject_1();
getClassObject_2();
getClassObject_3();
}
/**
* @throws ClassNotFoundException
* Способ третий:
* Класс можно получить, просто передав строковое имя данного класса, более расширенное.
* Но это делается с помощью метода в классе Class, который называется forName.
* Пока у этого метода есть имя, он более расширяемый и расширяемый.
*/
public static void getClassObject_3() throws ClassNotFoundException {
Выходной результат: класс bean.Person |
---|
String classNameString="bean.Person";
Class<?> class1=Class.forName(classNameString);
System.out.println(class1);
}
/**
* Способ 2:
* Любой тип данных имеет статический атрибут class для получения соответствующего объекта класса.
* относительно прост, но явного использования статических членов в классе недостаточно.
*/
public static void getClassObject_2() {
Class<Person> clazz = Person.class;
Выходной результат: правда |
---|
Class<Person> clazz1 = Person.class;
System.out.println(clazz == clazz1);
}
/**
* Способ 1: Способ получения объекта байткода: 1. Метод getClass() в классе Object. Чтобы использовать этот метод, вы должны указать конкретный класс и создать объект
*/
Выходной результат: человек, бегущий человек, runtrue |
---|
public static void GetClassObject_1() {
Person person = new Person();
Class<? extends Person> clazzClass = person.getClass();
Person p1 = new Person();
Class<? extends Person> clazz1 = p1.getClass();
System.out.println(clazz1 == clazzClass);
}
}
Пример 2: Отражение вызывает конструктор класса
package Test28;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectDemo2 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
// createNewObject();
createNewObject_2();
}
/**
* Создать экземпляр объекта без аргументов
*/
public static void createNewObject() throws ClassNotFoundException,
InstantiationException, IllegalAccessException {
// В первые дни, когда новый, сначала ищем файл байт-кода класса по имени нового класса и загружаем его в память,
// и создайте объект байтового файла, а затем создайте соответствующий объект Person байтового файла.
bean.Person person = new bean.Person();
// в настоящее время:
String name = "bean.Person";
// Находим файл класса с именем, загружаем его в память и генерируем объект класса.
Class<?> clazzClass = Class.forName(name);
// создаем объект этого класса
Object object = clazzClass.newInstance();
System.out.println(object.toString());
}
/**
* @throws Exception
* Создание экземпляра объекта с параметрами
*/
public static void createNewObject_2() throws Exception {
// ранее созданный класс с параметрами
bean.Person person = new bean.Person("Xiaoqiang", 39);
/*
* При получении воплощенного объекта в классе, соответствующем указанному имени,
Что, если объект инициализируется без построения нулевого параметра?
* Поскольку объект инициализируется через указанный конструктор,
* Таким образом, вы должны сначала получить конструктор. Это можно сделать с помощью объекта файла байт-кода.
* Метод: getConstructor(paramterTypes);
*/
String nameString = "bean.Person";
// Найдите файл класса с таким именем, загрузите его в память и сгенерируйте объект класса.
Class<?> class1 = Class.forName(nameString);
Constructor<?> constructor = class1.getConstructor(String.class,
int.class);
Объект объект = конструктор.newInstance("Сяо Мин", 32);
}
}
Пример 3. Получение полей в файле байт-кода.
package Test28;
import java.io.ObjectInputStream.GetField;
import java.lang.reflect.Field;
public class ReflectDemo3 {
public static void main(String[] args) throws ClassNotFoundException, Exception {
// TODO Auto-generated method stub
getFieldDemo();
}
/**
* @throws ClassNotFoundException
* @throws Exception
* Получить поля в файле байт-кода.
*/
public static void getFieldDemo() throws ClassNotFoundException, Exception {
Class<?> class1=Class.forName("bean.Person");
Field field=null;
field=class1.getField("age");//Получить только общедоступное
field=class1.getDeclaredField("age");//Получить только этот класс, но включить частные.
field.setAccessible(true);//Отменить проверку доступа к приватным полям, доступ методом перебора.
Object object=class1.newInstance();
field.set(object, 89);
Object o=field.get(object);
System.out.println(o);
}
}
Пример 4 Получить метод в файле байт-кода:
package Test28;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectDemo4 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
getMethodDemo();
getMethod_2();
getMethodDemo_3();
}
public static void getMethod_2() throws Exception {
Class<?> class1 = Class.forName("bean.Person");
Method method = class1.getMethod("show", null);
Object object = class1.newInstance();
Constructor constructor = class1.getConstructor(String.class, int.class);
Объект obj = конструктор.newInstance("Сяо Мин", 38);
method.invoke(obj, null);
}
/**
* @throws ClassNotFoundException
Получить все общедоступные функции в указанном классе
*/
public static void getMethodDemo() throws ClassNotFoundException {
Class clazzClass = Class.forName("bean.Person");// Получены все публичные методы
Method[]methods = clazzClass.getMethods();// Получить только все методы этого класса, включая приватные.
for (Method method : methods) {
System.out.println(method);
}
}
public static void getMethodDemo_3() throws Exception,
IllegalArgumentException, InvocationTargetException {
Class<?> clazzClass = Class.forName("bean.Person");
Method method = clazzClass.getMethod("paramMethod", String.class,
int.class);
Object obj = clazzClass.newInstance();
method.invoke(obj, "Сяоцян", 89);
}
}
Упражнение: Моделирование работы компьютера.
package cn.itcast.reflect.test;
public class Mainboard {
public void run() {
System.out.println("main board run....");
}
public void usePCI(PCI p) {//PCI p = new SouncCard();
if (p != null) {
p.open();
p.close();
}
}
}
package cn.itcast.reflect.test;
public interface PCI {
public void open();
public void close();
}
package cn.itcast.reflect.test;
public class NetCard implements PCI {
@Override
public void open() {
System.out.println("net open");
}
@Override
public void close() {
System.out.println("net close");
}
}
package cn.itcast.reflect.test;
public class SoundCard implements PCI {
public void open(){
System.out.println("sound open");
}
public void close(){
System.out.println("sound close");
}
}
package cn.itcast.reflect.test;
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
/*
* Компьютер работает.
*/
public class ReflectTest {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Mainboard mb = new Mainboard();
mb.run();
//Каждый раз, когда вы добавляете устройство, вам нужно изменить код, чтобы передать только что созданный объект
// mb.usePCI(new SoundCard());
//Можно ли это сделать без изменения кода.
// Не используйте new для завершения, а только получите его файл класса. Внутренне реализует действие по созданию объекта.
File configFile = new File("pci.properties");
Properties prop = new Properties();
FileInputStream fis = new FileInputStream(configFile);
prop.load(fis);
for(int x=0; x<prop.size(); x++){
String pciName = prop.getProperty("pci"+(x+1));
Class clazz = Class.forName(pciName);//Используйте класс для загрузки этого подкласса PCI.
PCI p = (PCI)clazz.newInstance();
mb.usePCI(p);
}
fis.close();
}
}