反射机制:动态获取类中的信息。可以理解为对类的解剖在一个已经做好的应用程序中,没有源码,只有对外提供的接口,所以不能创建新的对象。在反射机制中,只要实现接口,然后
反射机制:动态获取类中的信息。可以理解为对类的解剖 在一个已经做好的应用程序中,没有源码,只有对外提供的接口,所以不能创建新的对象。 在反射机制中,只要实现接口,然后在配置文件中写注明该类,在应用程序中就能自动加载
一、获取Class对象的方式: 方式1,Object类中的getClass()方法,想要用这种方式,必须要明确具体的类,并创建对象
car c=new car(); Class clazz=c.getClass(); car c1=new car(); Class clazz=c1.getClass(); Class clazz1=c1.getClass();//返回运行时类 System.out.println(clazz1==clazz);//true方式2,任何数据类型都具有一个静态的属性:.class来获取其对应的Class对象(相对简单,但是还要明确类中用到的静态成员,不够扩展)
Class clazz=car.class; Class clazz1=car.class; System.out.println(clazz1==clazz);//true方式3,只要通过给定的类的字符串名称就可以获取该类,扩展性强 可以用Class类中方法来完成:forName,只要指定名称即可
String className="com.Car.car";//必须指定包名的类, Class clazz=Class.forName(className);//该方法抛异常 System.out.println(clazz);二、获取Class中的构造函数
//早期:new 时,先根据被new的类的名称找到该类的字节码文件,加载进内存并创建该字节码文件对象,然后创建该字节码文件对应的person对象 //com.Car.person p=new com.Car.person(); //现在: String className="com.Car.person"; Class clazz=Class.forName(className);//获取到了class字节码文件对象 //Object obj=clazz.newInstance(); //创建该字节码文件对应的person对象,获取的是无参的构造函数对应的对象 Constructor cOnstructor=clazz.getConstructor(String.class,int.class);//创建该字节码对应的person对象,获取含参的构造函数对象 //通过该构造器的newInstance创建person对象含参的实例 constructor.newInstance("张三",15);三、获取Class中的字段
//创建对象 Class clazz=Class.forName("com.Car.person"); Object obj=clazz.newInstance(); //获取公共字段 Field f=clazz.getField("sex");//只能获取公共字段 System.out.println(f);//public java.lang.String com.Car.person.sex //获取指定字段属性的值 Object objField=f.get(obj); System.out.println(objField); //获取任Object何权限的字段 Field f1=clazz.getDeclaredField("age"); System.out.println(f1);//private int com.Car.person.age //获取特定对象的该字段值 //Object objField1=f1.get(obj);//java.lang.IllegalAccessException私有字段,不能访问java.lang.IllegalAccessException //若非要访问,则可以通过父类继承过来的方法,对私有字段的访问权限取消检查(暴力访问) f1.setAccessible(true); Object objField1=f1.get(obj); System.out.println(objField); //设置字段的值 f1.set(obj, 60);//在指定对象上字段设置值 System.out.println(f1.get(obj));四、获取Class中的方法
Class clazz=Class.forName("com.Car.person"); //Object obj=clazz.newInstance(); //获取包括父类的所有公共方法 Method [] method=clazz.getMethods(); for(Method m:method) { //System.out.println(m); } //获取本类中写的所有方法,不包含父类继承 Method[] method1=clazz.getDeclaredMethods(); for(Method m:method1) { //System.out.println(m); } //获取一个方法(无参) Method method2=clazz.getMethod("run", null); //System.out.println(method2);//public void com.Car.person.run() //想要让run中的值是某个对象的值 Constructor construct=clazz.getConstructor(String.class,int.class); Object obj=construct.newInstance("小强",20); //想要运行这个方法 method2.invoke(obj, null);//没返回值,直接在方法中输出了 //获取一个方法含参 Method method3=clazz.getMethod("show", int.class,int.class); method3.invoke(obj,80,63);五、反射练习 在主板中可以有声卡等插件,在以前的学习中的做法是如下这样的:
package com.Car1;public class mainBoard { public void run() { System.out.println("main.......run"); } public void useSoundCard(soundCard sc) { sc.open(); sc.close(); } public static void main(String[] args) { mainBoard mb=new mainBoard(); mb.useSoundCard(new soundCard()); //这样做法的坏处就是要加网卡的话,还要修改网卡的代码,扩展性差 }}package com.Car1;public class soundCard { public void open() { System.out.println("sound...open"); } public void close() { System.out.println("sound...close"); }}利用反射实现: 1)主板可以插入声卡网卡等,声卡等要实现个接口(PCI),这个接口是和主板关联的,比如主板中有public void usePCI(PCI p)方法,那么这个方法就能实现PCI中的功能(为简单起见,这个接口只有open、close功能)。 2)需要读配置文件用Properties类中的load方法加载文件到集合中,配置文件中放的是设备:类名,这样就可以通过遍历这个集合,将类名取出,利用类名创建对象p,然后再用主板的usePIC(p),就可以将这个设备运行起来了。 特别提示:若配置文件为空,则集合.size()==-1,则主板上没有可运行的,只能运行主板或者其他的接口。若需要添加PCI设备,只需要在配置文件中加入类名即可,不用修改主板代码(因为集合长度+1了),提高了程序的扩展性
package com.Car1;import java.io.*;import java.util.*;public class mainBoard { public void run() { System.out.println("main.......run"); } public void usePCI(PCI p)//无论是插入什么设备,只要是设备符合PCI这个接口,都有两个方法可用 { p.open(); p.close(); } public static void main(String[] args)throws Exception { mainBoard mb=new mainBoard(); mb.run(); FileInputStream fis=new FileInputStream("e:\\pci.prop");//配置文件,格式是设备:类名 Properties prop=new Properties(); prop.load(fis);//将流中对象加载进集合 for(int x=0;x 上一篇:C语言修仙
下一篇:没有了