标签:
什么是反射?反射就是将字节码中的各种成分映射到相应的java类中来,java反射技术自JDK1.1以来就出现了,目前大多数流行的框架都采用了这种技术,可见其重要性,这篇文章将详细介绍我对java反射技术的一些研究.
java中所有的类都有自己特有的一份字节码,当程序调用该类时,JVM便会将这份字节码装载到内存中来。在java中主要有三种方法来得到相应的字节码对象。
java中可以通过Class类的isPrimitive()方法判断当前的字节码是否为主类型,isEnum()判断字节码是否为枚举类。 isArray()判断字节码是否为数组类型。某个类和它所组成的数组分别持有的字节码也不相同,例如int.class==int[].class这种 写法在编译期就会被编译器阻止,因为编译器发现两边参与比较的对象不在一个继承树分支上。只有相同类型和相同维度的数组才会共用一个字节码对象,如int a1[]=new int[1], a2[]=new int[5];int a3[][]=new int[2][5];a1.getClass()==a2.getClass()为true,a2.getClass()==a3.getClass() 为false;
java中用getConstructor()和getConstructors()方法返回某一个public的构建器和所有public访问级 别的构建器,而getDeclaredConstructor()和getDeclaredConstructors()返回所有构建器中的某一个构建器 和所有的构建器。Constructor可以通过newInstance()方法创建一个该类的实例。如下例所示
Class clazz=String.class;
Constructor cs=clazz.getConstructor(StringBuffer.class);
String s=(String)cs.newInstance(new StringBuffer("abc"));
上面的代码相当于
String s=new String(new StringBuffer("abc"));
又如下例所示
String obj=String.class.getConstructor().newInstance();
上面的代码相当于
String obj=new String();
如果要得到所有的构建器可以按下面的方法做。
Constructor[] allCons=String.class.getDeclaredConstructors();
for(Construcotr con:allCons)
System.out.println(con.getName());
除了Constructor类中提供了newInstance()方法,Class类中也有一个类似的newInstance()方法,因为我们可以直接在得到字节码对象时便可生成该字节码的对象了。
ArrayList al=(ArrayList)ArrayList.class.newInstance();事实上得到构建器对象的那一步已经被封装在Class的newInstance()方法中。
public Object newInstance()
{
this.getConstructor().newInstance();
}
Class类中提供了getField()和getFields()得到public级别的字段中的某一个和所有public级别的字段,getDeclaredField()和getDeclaredFields()得到所有字段中的某一个和所有的字段。
如果某个字段是数组类型的,那么要对它进行反射还需要借助java.lang.reflect.Array来进行操作。有些时候得到的字段为 private访问级别的,如果这个时候想要读取和设值该字段一般情况下会报运行期异常,但是java反射技术也并不是对此无能为力,运用反射可以绕过编 译器的某些限制,来进行“暴力反射”。此时只需设置Field的setAccessible()为true就可以了。
Class类中同样提供了getMethod(),getMethods()用来得到得到public级别的方法和所有public的方法,以及 getDeclaredMethod()和getDeclaredMethods()方法用来得到任何访问级别的某一个方法和所有任何访问级别的方法.
网上的资料对于如何运用反射将内部类映射出来的资料非常之少,为此我特意花了一个多小时研究了一会儿,下面把研究的结果写到下面。
Class类本身还提供对于获取内部类字节码的方法,分别为getClasses和getDeclaredClasses(),其中 getClasses()只能得到访问级别为public的内部类,而getDeclaredClasses()则能得到所有声明了的内部类。
由于内部类可以分为实例内部类,静态内部类,匿名内部类,前面提到的getClasses()和getDeclaredClasses()目前还都 只能得到实例内部类和静态内部类,对于后面两种情况却无能为力,为此还需要采取一些特殊的手段才能针对匿名内部类进行反射操作。
package net.csdn.blog; public class ReflectInnerClass { public Runnable ta=new Runnable(){ public void run(){ System.out.println("匿名内部类中的方法被执行了"); } }; private class Inner2{ public Inner2(){ System.out.println("Inner2类被实例化了"); } } class Inner3{ public Inner3(){ System.out.println("Inner2类被实例化了"); } } public class Inner1{ public Inner1(){ System.out.println("Inner1类被实例化了"); } } }
下面对内部类进行反射
标签:
原文地址:http://www.cnblogs.com/king1302217/p/4200606.html