反射机制
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够条用它的任意一个方法和属性这种动态获取的信息以及动态调用对象的方法的功能成为Java语言的反射机制。
相对一个类文件进行解剖,只要获取到该类的字节码文件对象即可。
获取一个字节码对象的方式
1、Object类中的个getclass方法
想要用这种方式,必须要明确具体的类,并创建对象。如:Person p =new Person();Class clazz = p.getClass();
2、任何数据类型都具备一个静态的属性.class来获取其相对应的Class对象。
相对简单,但是还是要明确用到类中的静态成员,还是不够扩展。如:Class clazz = Persom.class;
3、只要通过给定的类的字符串名称就可以获得该类,更为扩展。可以用class类中的forName方法来实现。这种方法只要有名称即可,更为方便,扩展性更强。如:Class clazz =Class.forName("Person");
Class类中实用方法
在Class类中可以通过newInstance方法创建新的Object对象
getConstructor返回公共构造器对象Constructor,getConstructors返回所有公共构造器对象Constructor的数组;
getDeclaredConstructor返回任意构造器对象Constructor,getDeclaredConstructors返回所有任意构造器对象Constructor的数组;
注:在Constructor对象中,可以通过newInstance方法返回一个进行初始化的对象。
getField返回公共的字段对象Field。getFields返回所有公共字段对象的数组Field[];
getDeclaredField返回任意的字段对象(公共、保护、默认(包)访问和私有),getDeclaredFields返回所有任意的字段对象的数组;
注:Field对象中,用get方法可以获取Object对象;
getMethod返回公共的方法对象Method,getMethods返回所有公共的方法对象Method的数组;
getDeclaredMethod返回任意的Method对象,getDeclaredMethods返回所有任意的Method对象数组;
注:Method对象中,用ivoke方法调用底层方法。
Constructor、Field和Method类共有一个基类Accessible,该类中setAccessible方法是:对访问取消权限检查可用。将true作为参数传入,就是取消权限检查,俗称暴力访问。不推荐使用。
Class类中各方法练习:
public class Person {
private String name;
private int age;
public Person(){
this.name = null;
this.age = 0;
System.out.print(" no arguments constructor run ...."+name+":"+age);
}
public Person(String name,int age){
this.age = age;
this.name = name;
System.out.print("have arguments constructor run ....");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show(){
System.out.print("show run ...."+name+":"+age);
}
public void show1(String name,int age){
System.out.print("show1 run ...."+name+":"+age);
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
// TODO Auto-generated method stub
Class<?> clazz = Class.forName("Person");
//无参获取构造器
Constructor<?> con = clazz.getConstructor();
//有参获取构造器
Constructor<?> con1 = clazz.getConstructor(String.class,int.class);
//创建对象
Object obj = con.newInstance();
Object obj1 = con1.newInstance("xiaoqiang",48);
//创建字段
Field fie = clazz.getDeclaredField("name");
fie.setAccessible(true);
System.out.println(fie.get(obj));
System.out.println(fie.get(obj1));
//创建方法
Method me = clazz.getMethod("show");
me.invoke(obj);
System.out.println();
me.invoke(obj1);
Method me1 = clazz.getMethod("show1",String.class,int.class);
System.out.println();
me1.invoke(obj, "nihao",66);
System.out.println();
me1.invoke(obj1, "wangwu",98);
//System.out.print(fie.get(obj1));
}
}
运行结果
扩展性练习:
package PCI;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class PCIDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
// TODO Auto-generated method stub
MainBoard mb = new MainBoard();
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("PCI.properties");
prop.load(fis);
for(int x= 0; x < prop.size();x++){
String str = prop.getProperty("PCI"+(x+1));
Class<?> clazz = Class.forName(str);
PCI pci = (PCI)clazz.newInstance();
mb.run(pci);
}
}
}
package PCI;
public class MainBoard {
MainBoard(){
System.out.println("MainBorad run ....");
}
public void run(PCI pci){
pci.open();
pci.close();
}
}
package PCI;
public interface PCI {
public void open();
public void close();
}
package PCI;
public class Sound implements PCI {
@Override
public void open() {
// TODO Auto-generated method stub
System.out.println("Sound run ...");
}
@Override
public void close() {
// TODO Auto-generated method stub
System.out.println("Sound close ...");
}
}
package PCI;
public class Mouse implements PCI {
@Override
public void open() {
// TODO Auto-generated method stub
System.out.println("mouse run ...");
}
@Override
public void close() {
// TODO Auto-generated method stub
System.out.println("mouse close ...");
}
}
package PCI;
public class Keyboard implements PCI {
@Override
public void open() {
// TODO Auto-generated method stub
System.out.println("keyboard run ...");
}
@Override
public void close() {
// TODO Auto-generated method stub
System.out.println("keyboard close ...");
}
}
运行结果