您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

Java反 射

2026/2/6 12:50:00发布15次查看
java中java语言的反射机制:
java反射机制在运行状态中,对于任意一个类(class文件),都能知道这个类的所有属性和方法;
对于任意一个对象,能够调用它的任意一个方法和属性:
这种动态获取的信息以及动态调用对象的方法的动能称为java语言的反射机制。
动态获取类中信息,就是java反射,可以理解对类的解剖。有些应用程序是不能new对象的,但是可以动态加载类获取类信息。
如图所示,就像类是对象的描述一样,class类可以对字节码文件(.class文件)对象进行描述。
//早期:new时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,
//并创建该字节码文件对象,并接着创建该字节码文件的对应的person对象。
com.xidian.person p=new com.xidian.person();
//现在
string name=com.xidian.person;
//找寻该文件类文件,并加载进内存,并产生class对象。
class clazz=class.forname(name);
//如何产生该类的对象呢?
object obj=clazz.newinstance();
用反射类加载的方式,从表面上看形式较为复杂但是可扩展性却更强。原来需要自己在程序文件手动中创建一个对象,
现在只用在配置文件中写入字符串,就可以创建对应的对象。
问题:使用clazz.newinstance()只能使用空参构造函数,要使用参数列表的构造函数怎么办?
/*
* 获取指定名称对应类中的所体现的对象时,
* 而该对象初始化不使用空参构造函数该怎么办?

* 既然是通过指定的构造函数进行对象的初始化,
* 所以应该先获得到该构造函数。通过字节码文件即可完成。
* 该方法是:getconstructor(parametertypes)

* 在反射中构造器、字段、方法都是对象。
*/
string name=com.xidian.person;
class clazz=class.forname(name);
//获取到指定的构造函数对象
constructor constructor=clazz.getconstructor(string.class,int.class); //所有数据类型都可以用字节码文件.class来描述
//通过该构造器对象的newinstance方法进行对象的初始化。
object obj=constructor.newinstance(xiaoming,12);
获取指定字段的值:
//对私有字段的访问全校权限检查。暴力访问。
field_1.setaccessible(true);
object obj=clazz.newinstance();
field_1.set(obj,88);
object o=field_1.get(obj);
system.out.println(o);
获取函数:
method method=clazz.getmethod(show,null); //获取无参的方法
object obj=clazz.newinstance();
method.invoke(obj, null);
method method2=clazz.getmethod(parammethod,string.class,int.class); //获取有参的方法,方法名、参数列表
object obj2=clazz.newinstance();
method2.invoke(obj2, 小强,89); //invoke:对带有指定参数的指定对象调用由此 method 对象表示的底层方法。
反射的应用:
定义一个接口:
package com.xidian; public interface pci { public void open(); public void close(); }
定义一个接口实现类:
package com.xidian; public class soundcard implements pci{ public void open(){ system.out.println(sound open); } public void close(){ system.out.println(sound close); } }
定义一个主板:
package com.xidian; public class mainboard { public void run(){ system.out.println(main run...); } public void usepci(pci p){ if(p!=null){ p.open(); p.close(); } } }
测试:
package com.xidian; public class test { public static void main(string[] args){ mainboard mb=new mainboard(); mb.run(); mb.usepci(new soundcard()); //如果主板需要使用其他设备,必须重新修改代码,传递一个新创建的对象,可扩展性不好。 } }
虽然使用接口的方式已经降低了程序的耦合度,但是代码的可扩展性不好。
如果想增加主板的设备但是不想修改代码,改用反射的方式:
不用new来完成,而是只获取其class文件,在其内部是实现创建对象的动作。
用反射做配置是应该使用.xml,更加准确。而在此我们使用properties对象实现。
修改主函数代码:
public class test { public static void main(string[] args) throws ioexception, classnotfoundexception, instantiationexception, illegalaccessexception{ mainboard mb=new mainboard(); mb.run(); //mb.usepci(new soundcard()); //如果主板需要使用其他设备,必须重新修改代码,可扩展性不好。 file configfile=new file(pci.properties); properties prop=new properties(); //注意是将配置文件放在项目的一级目录下。 fileinputstream fis=new fileinputstream(configfile); prop.load(fis); for(int x=0;x 配置文件pci.properties:pci1=com.xidian.soundcard
当扩展设备的时候,只需要将设备程序写好,写好配置文件,而不需要改动主程序代码就可使用。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product