反射(Reflect)2010-5-7

来源:互联网 发布:淘宝配眼镜好吗 编辑:程序博客网 时间:2024/05/18 01:28

1、反射的基石----->Class

2、得到各个字节码对应的实例对象(Class类型)

 

  • 类名.Class,例如:System.class

 

  •   对象名.getClass( ),例如:new Date().getClass( )

 

  •   Class.forName“类名”

 

3、九个预定义Class实例对象

 

  •   Class.isPrimitive()查看是否是原始类型,如String.class.isPrimitive()//false

 

  • Int.class == Integer.Type;//true

 

4、数组类型的Class实例对象,用Class.isArray()判断,例如int[].class.isArray(),返回true

5、只要在源程序程序中出现的类型,都有各自的Class实例对象,例如:void.classint[].class

6、反射就是把Java类中的各种成分映射成相应的Java

7Constructor

 

  •   Constructor类代表某个类中的构造方法

 

  • 得到某个类的构造方法,

 

例如Constructor[]  cons= Class.forName(“java.lang.String”).getConstructor();

 

  • 得到某一个构造方法:Constructor constructor =

 

Class.forName(“java.lang.String”).getConstructor(StringBuffer.class)//参数类型

 

  •   创建实例对象:

 

通常方式:String str=new String(new StringBuffer(“abc”));

反射方式:String str = (String)constructor.newInstance(newStringBuffer(“abc”));

 

  • Class.newInstance( )省去了调用无参的Constructor.newInstance( );

 

该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。该方法的内部代码用到了缓存机制来保持默认的构造方法的实例对象。

 

 

8Filed

 

  • Filed类代表某个类中的一个成员变量

 

  •   实例代码

 

       ReflectPoint rp = new ReflectPoint(3, 5);

       Field filedY = rp.getClass().getField("y");//public int y;

       //filedYY的定义,而不是具体的Y的对象,要用它的get对象)方法获得

       System.out.println(filedY.get(rp1));

      

       //暴力反射

       Field fieldX = rp.getClass().getDeclaredField("x");//private int x;

       fieldX.setAccessible(true);//打开私有类型变量的访问权限

System.out.println(fieldX.get(rp1));

 

  • 替换任意一个对象中的所有String类型的成员变量所对应的字符串中的b改成a

 

//public String str1=”ball”,str2=”basketball”

private static void changeStringValue(Object obj) throws Exception {

    Field[]fields = obj.getClass().getFields();

    for(Field field :fields) {

//     if(field.getType().equals(String.class))

       if(field.getType() ==String.class) {

           StringoldValue = (String) field.get(obj);

           StringnewValue = oldValue.replace('b', 'a');

           field.set(obj,newValue);

       }

    }

}

9Method

 

  •   Method类代表某个类中的一个成员方法

 

  •   得到类中的某一个方法

 

String str1 = “abc”;

Method methodCharAt = String.class.getMethod("charAt", int.class);

 

  •   调用方法:

 

普通方式:System.out.println(str1.charAt(1));

反射方式:System.out.println(methodCharAt.invoke(str1, 1));

 

  • 如果str1位置为null,该方法为静态方法

 

  •   Jdk1.4jdk1.5invoke方法的区别

 

System.out.println(methodCharAt.invoke(str1, 1));//1.5

System.out.println(methodCharAt.invoke(str1, new Object[]{2}));//1.4需要传入数组

     

 

  • 调用传递过来的某个类的main方法

 

String startingClassName = args[0];//args[0]=package.TestArguments

Method mainMethod = Class.forName(startingClassName).

getMethod("main", String[].class);

//mainMethod.invoke(null, new Object[]{newString[]{"111","222","333"}});

mainMethod.invoke(null, (Object)new String[]{"111","222","333"});

//jdk1.5为兼容1.4以前版本,对传入的参数都作为一个Object[],并对其拆包

*******************************************************************

class TestArguments {

           public static void main(String[]args) {

              for(String arg: args){

                  System.out.println(arg);

              }

           }

}

10、数组反射

 

  •   数组的==,数组的父类

 

int[] a1 = new int[3];

int[] a2 = new int[4];

String[] a3 = new String[]{"a","b","c"};

System.out.println(a1.getClass().getName());//[I

 

  •   具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象

 

System.out.println(a1.getClass() == a2.getClass());//true

 

  • 代表数组的Class实例对象的getSuperClass( )方法返回的父类为Object类对应的Class

 

System.out.println(a1.getClass().getSuperclass().getName());

//java.lang.Object

 

  • 基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用;

 

  •   非基本类型的一维数组即可当Object类型,又可当做Object[]类型使用

 

Object aObj1 = a1; //没有报错

Object aObj2 = a3; //没有报错

Object[] aObj3 = a3; //没有报错

//Object[] aObj4 = a1;//编译时报错

System.out.println(a1); //[I@14318bb

System.out.println(a3); //[Ljava.lang.String;@ca0b6

 

  • Arrays.asList()方法处理int[]String[]时的差异

 

System.out.println(Arrays.asList(a1)); //[[I@14318bb]

System.out.println(Arrays.asList(a3)); //[a, b, c]

//1.4asList(Object[] obj)    1.5asList(T… a)使用了泛型

 

  • Arrays工具类用于完成对数组的反射操作