反射机制;
概念
java反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类中的所有属性和方法
对于任意一个对象,都能够调用它的任意一个方法和属性
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
想要对一个类文件进行解剖,只要获得该类的字节码对象即可
创建对象,是通过一个类的Class文件创建的
获取字节码对象的方式:
* 1.Object类中的getClass()方法。
* 想要用这种方式必须明确具体的类,并且
* 用该类创建对象。
* 2.任何数据类型都具备一个静态的属性.class来获取对应的Class对象。
* 但是还要明确类,用到类中的静态成员。
* 3.只要通过给定类的字符串就可以获取该类,更为扩展
* 可以用Class类中的forName()方法来搞定。
*/
程序
publicstatic void getClassObject_1(){
Personp1 = new Person();//用的是同一个类的class文件来创建的对象,那么字节码对象是一样的
Classclazz1 = p1.getClass();
Personp2 = new Person();
Classclazz2 = p2.getClass();
System.out.println(clazz1== clazz2);
}
publicstatic void getClassObject_2(){
Classclazz = Person.class;
Classclazz1 = Person.class;
System.out.println(clazz== clazz1);
}
publicstatic void getClassObject_3() throws ClassNotFoundException{
StringclassName = "com.sdut.day20.Person";//可以写在配置文件中
Classclazz = Class.forName(className);
System.out.println(clazz);
}
可以利用字节码文件对象来创建该类所对应的对象
Stringstr = "com.sdut.cn.Person";
找寻该名称类文件,并加载进内存,并产生Class对象
Classclazz = Class.forName(str);
利用字节码文件对象来创建类对象
Objectobj = clazz.newInstance();
使用带参数的构造方法来创建对象
Stringstr = "com.sdut.cn.Person";
找寻该名称类文件,并加载进内存,并产生Class对象
Classclazz = Class.forName(str);
//获取到了指定的构造函数对象
Constructorconstructor = clazz.getConstructor(String.class,int.class);
//通过该构造对象的newInstance方法进行对象的初始化
Objectobj = constructor.newInstance("看看",23);
获取类中的属性值
Classclazz = Class.forName("com.sdut.cn.Person");
Fieldfield = null;//clazz.getField("age")只能访问共有的
field= clazz.getDeclaredField("age");//只获取本类的属性,但包含私有
//对私有字段的访问取消权限检查,暴力访问
field.setAccessible(true);
Objectobj = class.newInstance();//通过对象获取属性
field.set(obj,23);为对象中age属性设置值
Objecto = field.get(Obj);
syso(o);
获取类中的方法
Method[]methods = clazz.getMethods()//获取字节码对象所对应的类的对象中的所有共有方法,包括父类
Method[]methods = clazz.getDeclaredMethods();//只获取本类中的方法,包括私有的方法
获取单个方法
Classclazz = Class.forName("com.sdut.day8.Person");
Methodmethod = clazz.getMethod("show",null);//该方法没有形参
Constructorconstructor =clazz.getConstructor(String.class,int.class);
Objectobj = constructor.newInstance("sd",3);//使用带参数的构造器创建对象
//如果是无参的。Objectobj = clazz.newInstance();
method.invoke(obj,null)//执行该方法,并且该方法没有实参
如果该方法有参数
Classclazz = Class.forName("com.sdut.day8.Person");
Methodmethod = clazz.getMethod("Param",String.class,int.class);//该方法有形参
Objectobj = clazz.newInstance();//创建一个对象
method.invoke(obj,"sdds",12);
使用扩展机制。应用
publicinterface PCI {
publicvoid open();
publicvoid close();
}
publicclass MainBoard {
publicvoid run(){
System.out.println("mainrun ------");
}
publicvoid usePCI(PCI p){
p.open();
p.close();
}
配置文件
PCI1= com.sdut.day20.SoundCard
扩展的功能
publicclass SoundCard implements PCI {
@Override
publicvoid open() {
System.out.println("soundcard open");
}
@Override
publicvoid close() {
System.out.println("soundcard close");
}
}
测试类
publicstatic void main(String[] args) throws Exception {
MainBoardmb = new MainBoard();
mb.run();
Propertiesprop = new Properties();
Filefile = new File("Rector.properties");
FileInputStreamin = new FileInputStream(file);
prop.load(in);
for(inti= 0; i<prop.size();i++){
Stringname = prop.getProperty("PCI"+(i+1));
Classclazz = Class.forName(name);//根据字符串创建该字符串所对应的字节码文件对象
Objectobj = clazz.newInstance();//得到该类的对象
mb.usePCI((PCI)obj);//将该类传递过去
}
in.close();
}