反射是什么?
一个类有多个组成部分,例如,构造函数(创建对象,完成对象初始化),成员变量(封装数据),方法(执行功能)。反射就是加载类,并反射出类的各个组成部分;
1、加载类,获取类的字节码可以通过三种形式来获取
Class cl=Class.forName("com.java.xiong.reflet0301.Person"); Class cl1=new Person().getClass(); Class cl2=Person.class;
2、通过获取得到类的字节码之后就可以来反射类:通过Class对象如下的几个方法可以获取类的构造函数,成员变量与方法
Constructor<T> |
getConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法 |
Constructor<T> |
getDeclaredConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法 |
Field |
getField(String name) 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。 |
Field |
getDeclaredField(String name) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 |
Method |
getMethod(String name,Class<?>... parameterTypes) 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 |
Method |
getDeclaredMethod(String name,Class<?>... parameterTypes) 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 |
实例:
package com.java.xiong.reflet0301; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.junit.Test; public class Test1 { //反射类的构造函数 //无参构造函数 @Test public void test() throws Exception{ //获取Class对象 Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person"); //获取类构造函数的对象 Constructor<?> cons=cl.getConstructor(); //获取类的对象 Person person=(Person)cons.newInstance(); System.out.println(person.aa); } //带参数的构造函数 @Test public void test1() throws Exception{ Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person"); //构造函数传入参数的参数类型 Constructor<?> cons=cl.getConstructor(String.class); //构造函数的参数的值 Person person=(Person)cons.newInstance("xiong"); System.out.println(person.aa); } @Test public void test2()throws Exception{ Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person"); Constructor<?> cons=cl.getConstructor(String.class,int.class); Person person=(Person)cons.newInstance("xiong",23); System.out.println(person.aa); } //反射类的方法 @Test public void fc()throws Exception{ //获取Class对象 Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person"); //获取方法的对象 Method method=cl.getMethod("fc"); //执行方法 method.invoke(new Person()); } @Test public void fc1()throws Exception{ Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person"); //第一个参数表示方法名 后面的可变参数表示 方法中的参数的参数类型 Method method=cl.getMethod("fc", String.class,int.class); //一个表示执行者的对象 后面的可变参数表示方法的参数值 method.invoke(new Person(), "xiong",23); } @Test public void fc2()throws Exception{ Class<?>cl=Class.forName("com.java.xiong.reflet0301.Person"); Method method=cl.getMethod("fc", String.class); //获取方法的返回值 Object []invoke =(Object[]) method.invoke(new Person(),"xiong"); System.out.print(invoke[0]); } @Test public void fc3()throws Exception{ Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person"); //调用类的私有方法用getDeclaredMethod Method method=cl.getDeclaredMethod("privatefc"); System.out.println(method.getName()); //method.invoke(new Person()); 类私有方法不能执行 method.setAccessible(true);//获取私有访问权限 method.invoke(new Person()); } @Test public void fc4()throws Exception{ Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person"); Method method=cl.getMethod("arr", String[].class); //当反射类的方法的参数是数组时 需要特别的注意 //因为在jdk1.4的时候 当方法有多个参数aa(String a,String b)时 invoke()的方法是invoke(new Person(),new []Object{"a","b"}) 这个Object //就是表示两个参数 a和b的值 所以jdk1.5时为了兼容1.4 当方法的参数是数组时也是拆开来传入的 //两种方法来解决这个问题 method.invoke(new Person(),new Object[]{new String[]{"1","2"}}); method.invoke(new Person(),(Object)new String[]{"1","2"}); } //反射类的成员变量 @Test public void bl()throws Exception{ Person person=new Person(); Class<?> cl=Class.forName("com.java.xiong.reflet0301.Person"); //获取字段 Field file=cl.getField("aa"); Field files=cl.getField("A"); Class<?> types=file.getType();//获取字段的类型 if(types.equals(String.class)){ //获取那个类的对象的字段 String str1=(String)file.get(person); System.out.println(str1); file.set(person, "file"); System.out.println(person.aa); String str2=(String)file.get(person); System.out.println(str2); } System.out.println(files.get(person)); } }
package com.java.xiong.reflet0301; public class Person { public String aa="aa"; public static final int A=1; //构造函数 public Person(){ System.out.println("Person()"); } public Person(String name){ System.out.println("Person(String name) name :"+name); } public Person(String name,int age){ System.out.println("Person(String name,int age)"+" name:"+name+" age:"+age); } //方法 public void fc(){ System.out.println("fc()"); } public void fc(String name,int age){ System.out.println("fc(String name) name:"+name +"age:"+age); } public String [] fc(String name ){ return new String[]{name}; } private void privatefc(){ System.out.println("privatefc()"); } public void arr(String []arg){ System.out.println("arr(String []arg)"); } }
原文:http://blog.csdn.net/x605940745/article/details/20222105