做电商网站的/株洲网络推广
在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法,并能够实例化该类成对象,并调用其方法和成员。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
JAVA中的反射机制是一种能够大大增强程序扩展性的技术。当一个程序封装完成后(生成exe文件),如果想要对该程序进行功能扩展,不用进行代码的重新修改(也不可能拿到源码),只要修改配置文件(一般是XML)就可以完成扩展。
这样的程序为外部提供了一个接口,只要按照该接口的规则定义一个对象(功能),即可以为应用程序扩展该功能。
可以这样比喻,你买了一块电脑主板(封装好的程序),此时你想要添加一块声卡(要扩展的功能),此时只能够通过一个pci接口(应用程序提供的接口)来进行扩展。声卡的接口必须符合PCI的规则才可以被主板使用。通过添加驱动程序(修改XML配置文件)来进行扩展功能。
具体到代码实现分为以下几步:
1、定义一个接口(PCI)及一系列的方法用作加载功能。
2、定义一个对象并且实现该接口,复写其中的方法。
3、在配置文件中添加该对象的名称(全名,包括路径)键值对。
4、定义一个输入流,读入配置文件进properties集(健壮性判断);
5、使用for循环挨个获取properties集中的对象名称;
6、获取名称后用Class加载这个类,并实例化一个该对象(可以直接进行类型强转,因为已知是PCI接口)。
7、使用对象。
1 File configFile = new File("pci.properties");2
3 Properties prop = newProperties();4 FileInputStream fis = newFileInputStream(configFile);5
6prop.load(fis);7
8 for(int x=0; x
10 String pciName = prop.getProperty("pci"+(x+1));11
12 Class clazz = Class.forName(pciName);//用Class去加载这个pci子类。
13
14 PCI p = (PCI)clazz.newInstance(); //PCI接口已经定义好了,有open和close两个方法
15
16 mb.usePCI(p);//mb是主板对象,定义了一个使用PCI接口对方法
17}18
19 fis.close();
不仅如此,有时还需要或得该对象的有参数构造器,成员,成员方法
1、创建对象实例
//1、指定该类的名称
String className = "cn.itcast.bean.Person";//2、通过Class类的forName()方法获取该类(从.class文件中获取)
Class clazz =Class.forName(className);//3、通过Class对象的newInstance()方法创建对象,无参构造器
Object obj = clazz.newInstance();
问题:
1、从上面代码可以发现,如果要用有参构造器实例化对象的话就不行
2、实例化的对象时Object类,要想办法downcast
2、获取其任意构造器
String name = "cn.itcast.bean.Person";//1、找寻该名称类文件,并加载进内存,并产生Class对象。
Class clazz =Class.forName(name);//2、获取到了指定的构造函数对象,构造器也有自己的对象。getConstructor(,)的参数列表对应于所需构造器的参数列表的类对象
Constructor constructor = clazz.getConstructor(String.class,int.class);//3、通过该构造器对象的newInstance方法进行对象的初始化。
Object obj = constructor.newInstance("小明",38);
3、获取其成员
Class clazz = Class.forName("cn.itcast.bean.Person");
Field field= null;//clazz.getField("age");//只能获取公有的,
field= clazz.getDeclaredField("age");//只获取本类,但包含私有。 参数为成员名//对私有字段的访问取消权限检查。暴力访问。
field.setAccessible(true);
Object obj=clazz.newInstance();
field.set(obj,89);//将obj对象中的对应field成员值设为89
Object o= field.get(obj);//返回obj对象中的field成员的值
System.out.println(o);//89
4、获取方法(类似于构造器的获取)
public static void getMethodDemo_3() throwsException {
Class clazz= Class.forName("cn.itcast.bean.Person");
Method method= clazz.getMethod("paramMethod", String.class,int.class);//第一个参数是方法名,考虑到重载,所以后面要加上参数列表来定位唯一的方法
Object obj=clazz.newInstance();
method.invoke(obj,"小强",89);//调用obj对象中的method方法,且传递了参数。
}public static void getMethodDemo() throwsException {
Class clazz= Class.forName("cn.itcast.bean.Person");
Method[] methods= clazz.getMethods();//获取的都是公有的方法。
methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有。 返回一个方法数组,方法对象数组
for(Method method : methods){
System.out.println(method);
}
}