java reflection学习

编程技术  /  houtizong 发布于 3年前   53

参考:

【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 objectConstructor[] constructors = aClass.getConstructors();// 如果你已经知道构造方法的参数,也可以用以下代码获取具体方法Class aClass = ...//obtain class objectConstructor constructor =        aClass.getConstructor(new Class[]{String.class});


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

  Constructor constructor = ... // obtain constructor - see aboveClass[] parameterTypes = constructor.getParameterTypes();


16.实例化对象

  //get constructor that takes a String as argumentConstructor constructor = MyObject.class.getConstructor(String.class);MyObject myObject = (MyObject)        constructor.newInstance("constructor-arg1");// 实际参数列表


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

16.获取属性信息

  Class aClass = ...//obtain class objectField[] methods = aClass.getFields();// 如果你知道属性名字Class  aClass = MyObject.classField field = aClass.getField("someField");


17.获取属性名字

  Field field = ... //obtain field objectString fieldName = field.getName();


18.获取属性类型

  Field field = aClass.getField("someField");Object fieldType = field.getType();


19.获取或设置属性值

  Class  aClass = MyObject.classField field = aClass.getField("someField");MyObject objectInstance = new MyObject();// 获取属性值Object value = field.get(objectInstance);// 设置属性值field.set(objetInstance, value);

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

20.获取方法

  Class aClass = ...//obtain class objectMethod[] methods = aClass.getMethods();// 获取具体的某一方法,有参数Class  aClass = ...//obtain class objectMethod method =    aClass.getMethod("doSomething", new Class[]{String.class});// 获取具体的某一方法,无参数Class  aClass = ...//obtain class objectMethod method =    aClass.getMethod("doSomething", null);


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

  Method method = ... // obtain method - see aboveClass[] parameterTypes = method.getParameterTypes();Class returnType = method.getReturnType();

 

22.使用method对象执行方法

  //get method that takes a String as argumentMethod 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什么的。。。。。。。

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

 

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客