代表字节码对象的Class
java中所有的类都有自己特有的一份字节码,当程序调用该类时,JVM便会将这份字节码装载到内存中来。在java中主要有三种方法来得到相应的字节码对象。
1.通过类的实例的getClass()方法获取,如 Class clazz=new Date().getClass()得到了Date类的字节码对象。
2.通过类的class属性获取。如Class clazz=String.class或者Class clazz=System.class.值得注意的是,java中八个主类型(byte,char,short,int,long,float,double,boolean)和一个返回类型void都有class属性,并且都返回自己的字节码对象。如int.class,boolean.class,float.class等。其中他们的包装类的TYPE属性也分别返回它们主类型的那份字节码,如int.class==Integer.TYPE为true,void.class==Void.TYPE为true;
3.通过Class类的forName()方法获取,如Class clazz=Class.forName("java.lang.Math");
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;
对内部类的反射
Class类本身还提供对于获取内部类字节码的方法,分别为getClasses和getDeclaredClasses(),其中getClasses()只能得到访问级别为public的内部类,而getDeclaredClasses()则能得到所有声明了的内部类。
由于内部类可以分为实例内部类,静态内部类,匿名内部类,前面提到的getClasses()和getDeclaredClasses()目前还都只能得到实例内部类和静态内部类,对于后面两种情况却无能为力,为此还需要采取一些特殊的手段才能针对匿名内部类进行反射操作。
[java] view plaincopy
01.package net.csdn.blog;
02.
03.public class ReflectInnerClass {
04.
05.
06.
07. public Runnable ta=new Runnable(){
08. public void run(){
09. System.out.println("匿名内部类中的方法被执行了");
10. }
11. };
12.
13.
14. private class Inner2{
15. public Inner2(){
16. System.out.println("Inner2类被实例化了");
17. }
18. }
19.
20. class Inner3{
21. public Inner3(){
22. System.out.println("Inner2类被实例化了");
23. }
24. }
25. public class Inner1{
26. public Inner1(){
27. System.out.println("Inner1类被实例化了");
28. }
29. }
30.}
下面对内部类进行反射
[java] view plaincopy
01.package net.csdn.blog;
02.
03.import java.lang.reflect.InvocationTargetException;
04.import java.lang.reflect.Modifier;
05.
06.public class ReflectInnerClassTest {
07.
08. public static void main(String args[]){
09. ReflectInnerClass ric=new ReflectInnerClass();
10. try {
11. reflectInnerClass(ric);
12. } catch (Exception e) {
13. e.printStackTrace();
14. }
15. }
16.
17. private static void reflectInnerClass(ReflectInnerClass ric) throws InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, NoSuchFieldException {
18. Class clazz=ric.getClass();
19. Class classes[]=clazz.getDeclaredClasses();
20. for(Class c:classes){//对成员内部类进行反射
21. int i=c.getModifiers();
22. String s=Modifier.toString(i);
23. if(s.contains("static"))//静态内部类的处理
24. c.getConstructor().newInstance();
25. else//实例内部类的处理
26. c.getConstructor(ric.getClass()).newInstance(ric);
27. }
28. //由于匿名内部类没有构建器,因此无法创建实例,也无法直接访问其中的方法,但可以通过下面的方式巧秒的执行其中的方法或成员变量。
29. Runnable r=(Runnable)(clazz.getField("ta").get(ric));
30. r.run();
31.
32. }
33.}
|