java反射

来源:互联网 发布:hd软件 编辑:程序博客网 时间:2024/06/05 08:26

反射技术

反射技术一般用来作框架使用。框架一般都是都是通过读取配置文件来运行指定类文件。

反射就是加载类,并解剖类的各个组成部分。

Class常用method(省略参数列表)

getConstructor()getMethod()getField()

getDeclaredConstructor()getDeclareMethod()getDeclareField()

区别:

没有declared的只能获取类中的public的声明部分,使用declared能获得private的声明部分。

 

反射类的Constructor示例:

 

package com.summer.day1;public class Person {private int age=10;private String name= "aaa";public Person() {super();System.out.println(age+name);}public Person(int age, String name) {super();this.age = age;this.name = name;System.out.println(age+name);}private Person(String name) {super();this.name = name;System.out.println(age+name);};public void eat(String food){System.out.println(food);}public static String run(String run){System.out.println(run);return run+" faster";}public static void main(String[] args){System.out.println("main");}}
package com.summer.day1;import java.lang.reflect.Constructor;import org.junit.Test;public class Refelct {@Testpublic void test1() throws Exception{Class clazz= Class.forName("com.summer.day1.Person");Constructor constructor=clazz.getConstructor(null);constructor.newInstance();}@Testpublic void test2() throws Exception{Class clazz= Class.forName("com.summer.day1.Person");//如果使用getConstructor则由于private权限问题会在下面一句报错Constructor constructor=clazz.getDeclaredConstructor(String.class);//没有设置成true则在newInstance时报错constructor.setAccessible(true);constructor.newInstance("bbb");}@Testpublic void test3() throws Exception{Class clazz= Class.forName("com.summer.day1.Person");//本质是test1,找到无参构造函数,然后newInstance//算是test1的简写形式clazz.newInstance();}}


 

反射类的Method示例:

 

package com.summer.day1;import java.lang.reflect.Method;import org.junit.Test;public class MethodDemo {@Testpublic void test1() throws Exception{Class clazz= Class.forName("com.summer.day1.Person");//指明函数名和传递参数列表Method method = clazz.getMethod("eat", String.class);Person p=new Person();//指明调用的对象和参数值method.invoke(p, "apple");}@Testpublic void test2() throws Exception{Class clazz= Class.forName("com.summer.day1.Person");Method method = clazz.getMethod("run", String.class);//如果方法为静态的可以不需要指定调用的对象,用null//方法的结果为invoke的返回结果String ans=(String) method.invoke(null, "run");System.out.println(ans);}@Test/** * 调用main方法需要注意main(String[] args)的参数传递 * 这是因为在jdk1.5前没有可变参数所引起的,没有可变参数前是invoke(Object,Object[]), * 他会将值列表Object[]中的内容提取出来然后根据函数名和参数列表去找对应的method * 因此method.invoke(null, new String[]{"aa","bb"});会被认为是去寻找main(String,String) * 所以找不到,现实参数列表的个数错误 * @throws Exception */public void test3() throws Exception{Class clazz= Class.forName("com.summer.day1.Person");Method method = clazz.getMethod("main", String[].class);/* * method.invoke(null, new String[]{"aa"}); *这个居然显示参数类型不匹配,只有一个值的数组居然不可以 *//* * method.invoke(null, new String[]{"aa","bb"}); * 这个现实参数列表的个数错误 *//* method.invoke(null, (Object)new String[]{"aa","bb"}); * 这样将数组变为了类,invoke不需要去提取类中的内容,所以能通过 **/ method.invoke(null, new Object[]{new String[]{"aa","bb"}});}}

反射类的Field类似,主要方法get()set()方法类似于ConstructornewInstanceMethodinvoke方法。对于私有的field可以使用getDeclareField()得到,但是如果想get的话要先修改setAccessibletrue)。字段如果不是static,则在get字段时需要指明是那个实力的field

 

 

 

0 0