java reflection学习

参考:

【1】http://dev.csdn.net/article/49/49876.shtm

【2】http://tutorials.jenkov.com/java-reflection/index.html

Java reflection

什么是java反射机制? java机制能干什么?

从理论上说,java reflection 就是对运行中的class进行“自审”。允许程序对运行中的类、接口等重的属性、方法进行检测。常用的地方有:java bean、Hibernate的数据库映射等。

java reflection的包“java.lang.reflect”。

1.获取操作类的java.lang.Class对象:

    Class c = Class.forName("java.lang.String");
    Class c = int.class;
    Class c = Integer.TYPE;

2.获取诸如getDeclearedMethods方法,以取得该类中定义的所有方法的列表。

    Class c = Class.forName("java.lang.String");
    Method m[] = c.getDeclearedMethods();


3.操作这些信息

     System.out.println(m[0].toString());

常用操作:

1.获取类的methods

Class c = Class.forName("constructor1");
Method[] m[] = c.getDeclearedMethods();

getDeclearedMethods()://获取类中所有方法。
getMethods()://还可以获取继承来的各个方法信息。
2.获取构造器

  Class cls = Class.forName("constructor1");
  Constructor ctorlist[] = cls.getDeclaredConstructors();

3.获取所有属性

  Class cls = Class.forName("reflection.field1");
 Field fieldlist[] = cls.getDeclaredFields();


4.根据方法的名称来执行方法

      import java.lang.reflect.Method;

/*

 * 根据方法的名称来执行方法

 */

public class Method2 {

    public int add(int a, int b) {

        return a + b;

    }

    public static void main(String args[]) {

        try {

            Class cls = Class.forName("reflection.method2");

            

            // 用于查找一个具有两个整型参数且名为 add 的方法

            Class partypes[] = new Class[2];

            partypes[0] = Integer.TYPE;

            partypes[1] = Integer.TYPE;

            Method meth = cls.getMethod("add", partypes);

            

            // 实例化对象,并构造参数列表

            Method2 methobj = new Method2();

            Object arglist[] = new Object[2];

            arglist[0] = new Integer(37);

            arglist[1] = new Integer(47);

            

            // 执行方法,并获取结果

            Object retobj = meth.invoke(methobj, arglist);

            Integer retval = (Integer) retobj;

            System.out.println(retval.intValue());

        } catch (Throwable e) {

            System.err.println(e);

        }

    }

}


5.执行构造器,创建新的对象实例

  package reflection;

import java.lang.reflect.*;



public class constructor2 {

    public constructor2() {

    }



    public constructor2(int a, int b) {

        System.out.println("a = " + a + " b = " + b);

    }



    public static void main(String args[]) {

        try {

            Class cls = Class.forName("reflection.constructor2");

            //  用于查找一个具有两个整型参数的构造方法

            Class partypes[] = new Class[2];

            partypes[0] = Integer.TYPE;

            partypes[1] = Integer.TYPE;

            Constructor ct = cls.getConstructor(partypes);

            

            // 构造参数列表

            Object arglist[] = new Object[2];

            arglist[0] = new Integer(37);

            arglist[1] = new Integer(47);

            

            // 执行方法,并获取对象实例

            Object retobj = ct.newInstance(arglist);

        } catch (Throwable e) {

            System.err.println(e);

        }

    }

}


6.改变字段(域)的值

reflection 的还有一个用处就是改变对象数据字段的值。reflection 可以从正在运行的程序中根据名称找到对象的字段并改变它,下面的例子可以说明这一点:

  
import java.lang.reflect.*;

public class field2 {

    public double d;

    public static void main(String args[]) {

        try {

            Class cls = Class.forName("field2");

            Field fld = cls.getField("d");

            field2 f2obj = new field2();

            System.out.println("d = " + f2obj.d);

            fld.setDouble(f2obj, 12.34);

            System.out.println("d = " + f2obj.d);

        } catch (Throwable e) {

            System.err.println(e);

        }

    }

}

这个例子中,字段 d 的值被变为了 12.34。
7.使用数组
创建的操作数组。数组在 Java 语言中是一种特殊的类类型,一个数组的引用可以赋给 Object 引用。观察下面的例子看看数组是怎么工作的:

  
import java.lang.reflect.*;
public class array1 {

    public static void main(String args[]) {

        try {

            Class cls = Class.forName("java.lang.String");

            Object arr = Array.newInstance(cls, 10);

            Array.set(arr, 5, "this is a test");

            String s = (String) Array.get(arr, 5);

            System.out.println(s);

        } catch (Throwable e) {

            System.err.println(e);

        }

    }

}

例中创建了 10 个单位长度的 String 数组,为第 5 个位置的字符串赋了值,最后将这个字符串从数组中取得并打印了出来。

下面这段代码提供了一个更复杂的例子:

  
import java.lang.reflect.*;
public class array2 {

    public static void main(String args[]) {

        int dims[] = new int[]{5, 10, 15};

        Object arr = Array.newInstance(Integer.TYPE, dims);

        Object arrobj = Array.get(arr, 3);

        Class cls = arrobj.getClass().getComponentType();

        System.out.println(cls);

        arrobj = Array.get(arrobj, 5);

        Array.setInt(arrobj, 10, 37);

        int arrcast[][][] = (int[][][]) arr;

        System.out.println(arrcast[3][5][10]);

    }

}


例中创建了一个 5 x 10 x 15 的整型数组,并为处于 [3][5][10] 的元素赋了值为 37。注意,多维数组实际上就是数组的数组,例如,第一个 Array.get 之后,arrobj 是一个 10 x 15 的数组。进而取得其中的一个元素,即长度为 15 的数组,并使用 Array.setInt 为它的第 10 个元素赋值。

注意创建数组时的类型是动态的,在编译时并不知道其类型。
------------class--------

8.获取类名

  
// 获取类的全名(包名+类名)

Class aClass = MyObject.class;

String className = aClass.getName();

// 获取类名(不包含包名)

Class aClass = MyObject.class;

String simpleClassName = aClass.getSimpleName();


9.获取修饰符

 int mod = *.getModifiers();

Modifier.toString(mod));


10.获取包信息

  
Package package = aClass.getPackage();


11.获取父类

  
Class superclass = aClass.getSuperclass();


12.获取实现的接口

  Class[] interfaces = aClass.getInterfaces();


13.others

  Constructor[] constructors = aClass.getConstructors();

Method[] method = aClass.getMethods();

 Method[] method = aClass.getFields();

-------Constructor ------------

14.获取构造方法

  Class aClass = ...//obtain class object

Constructor[] constructors = aClass.getConstructors();

// 如果你已经知道构造方法的参数,也可以用以下代码获取具体方法

Class aClass = ...//obtain class object

Constructor constructor =

        aClass.getConstructor(new Class[]{String.class});


15.获取构造方法的参数信息

  Constructor constructor = ... // obtain constructor - see above

Class[] parameterTypes = constructor.getParameterTypes();


16.实例化对象

  //get constructor that takes a String as argument

Constructor constructor = MyObject.class.getConstructor(String.class);

MyObject myObject = (MyObject)
        constructor.newInstance("constructor-arg1");// 实际参数列表


---------Fileds------------------

16.获取属性信息

  Class aClass = ...//obtain class object

Field[] methods = aClass.getFields();

// 如果你知道属性名字

Class  aClass = MyObject.class

Field field = aClass.getField("someField");


17.获取属性名字

  Field field = ... //obtain field object

String fieldName = field.getName();


18.获取属性类型

  
Field field = aClass.getField("someField");

Object fieldType = field.getType();


19.获取或设置属性值

  Class  aClass = MyObject.class

Field field = aClass.getField("someField");

MyObject objectInstance = new MyObject();

// 获取属性值

Object value = field.get(objectInstance);

// 设置属性值

field.set(objetInstance, value);

------------Methods-------------

20.获取方法

  Class aClass = ...//obtain class object

Method[] methods = aClass.getMethods();

// 获取具体的某一方法,有参数

Class  aClass = ...//obtain class object

Method method =

    aClass.getMethod("doSomething", new Class[]{String.class});

// 获取具体的某一方法,无参数

Class  aClass = ...//obtain class object

Method method =

    aClass.getMethod("doSomething", null);


21.获取方法的参数或返回类型

  
Method method = ... // obtain method - see above

Class[] parameterTypes = method.getParameterTypes();

Class returnType = method.getReturnType();

 

22.使用method对象执行方法

  
//get method that takes a String as argument

Method method = MyObject.class.getMethod("doSomething", String.class);

Object returnValue = method.invoke(null, "parameter-value1");


----------gets & sets----------------

23.set/get方法

  public static void printGettersSetters(Class aClass){

  Method[] methods = aClass.getMethods();



  for(Method method : methods){

    if(isGetter(method)) System.out.println("getter: " + method);

    if(isSetter(method)) System.out.println("setter: " + method);

  }

}

public static boolean isGetter(Method method){

  if(!method.getName().startsWith("get"))      return false;

  if(method.getParameterTypes().length != 0)   return false;  

  if(void.class.equals(method.getReturnType()) return false;

  return true;

}

public static boolean isSetter(Method method){

  if(!method.getName().startsWith("set")) return false;

  if(method.getParameterTypes().length != 1) return false;

  return true;

}


----------访问私有属性(private fileds)---------------

24.访问私有属性

Class.getField(String name) 和 Class.getFields() 只能获取public的属性;

如果想获取私有属性,你需要使用:Class.getDeclaredField(String name)  或 Class.getDeclaredFields()

一般来说,一个类的私有属性在类之外是不能访问的,可通过java反射机制,却能够做到这一点。

示例代码:

类:

  public class PrivateObject {

  private String privateString = null;

  public PrivateObject(String privateString) {

    this.privateString = privateString;

  }

}


私有属性访问代码

  
PrivateObject privateObject = new PrivateObject("The Private Value");

Field privateStringField = PrivateObject.class.

            getDeclaredField("privateString");
privateStringField.setAccessible(true);// 将该属性设置为可见

// 你可以访问私有属性了,呵呵

String fieldValue = (String) privateStringField.get(privateObject);

System.out.println("fieldValue = " + fieldValue);


-----------access private methods---------------

25.和上一个比较类似

类:

  
public class PrivateObject {

  private String privateString = null;

  public PrivateObject(String privateString) {

    this.privateString = privateString;

  }

  private String getPrivateString(){

    return this.privateString;

  }

}


代码:

  
PrivateObject privateObject = new PrivateObject("The Private Value");

Method privateStringMethod = PrivateObject.class.

        getDeclaredMethod("getPrivateString", null);

privateStringMethod.setAccessible(true);

String returnValue = (String)

        privateStringMethod.invoke(privateObject, null);  

System.out.println("returnValue = " + returnValue);


---------------Array---------------------

26.创建Array

创建一个int[3],第一个参数类型,第二个参数大小

  int[] intArray = (int[]) Array.newInstance(int.class, 3);


27.访问数组

  int[] intArray = (int[]) Array.newInstance(int.class, 3);

Array.set(intArray, 0, 123);
Array.set(intArray, 1, 456);
Array.set(intArray, 2, 789);

System.out.println("intArray[0] = " + Array.get(intArray, 0));
System.out.println("intArray[1] = " + Array.get(intArray, 1));
System.out.println("intArray[2] = " + Array.get(intArray, 2));


--------------others----------------------

另外java反射机制还可以访问:注释Annotations、泛型Generics、代理Proxies什么的。。。。。。。

因为太晚了缘故 暂时到这,以后再补充吧

 

你可能感兴趣的:(java,C++,c,Hibernate,C#)