`
yianpuodiaotu
  • 浏览: 241700 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

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 Reflection (JAVA反射)

    ### Java反射机制详解 #### 一、Java反射机制概述 反射是Java编程语言的一个关键特性,它赋予了Java程序在运行时自我检查的能力,并...通过本文的学习,希望能够帮助大家更好地理解和运用反射这一重要的Java特性。

    JAVA REFLECTION IN ACTION

    读者可以学习如何将反射技术应用于解决具体问题,甚至可以直接采用书中的示例代码进行定制化开发,以满足特定需求。 #### 模式与最佳实践 《JAVA反射在行动》还介绍了一些基于反射的编程模式和最佳实践,帮助读者...

    Java Reflection In Action

    本书《Java Reflection in Action》深入浅出地讲解了Java反射技术的各种应用场景和技术细节。书中通过一系列生动的例子展示了如何安全有效地使用反射技术解决实际问题。例如: 1. **使用反射进行动态代理**:介绍了...

    Java Reflection in Action_PDF+sample source

    《Java Reflection in Action》这本书深入探讨了这一主题,为开发者提供了理解和运用反射的强大工具。这本书包含了PDF版的全文以及示例源代码,帮助读者通过实践来学习。 1. **反射基础**: - 反射API:`java.lang...

    javaReflection反射机制.ppt

    之前上课的时候老师总结的JavaReflection反射学习资料,内容简单易懂,浅显易懂,适合小白入手学习。。

    Java Reflection in Action

    无论是作为学习资料,还是作为参考手册,本书都将是Java开发者书架上不可或缺的一本好书。通过阅读本书,开发者们可以克服反射技术的神秘感,将其转化为实用的编程武器,在各种应用场景中发挥其强大的潜力。

    Manning - Java Reflection in Action.pdf

    《Java反射技术实战》这本书由Ira R. Forman和Nate Forman撰写,由Manning出版社出版,是一本深入探讨Java反射技术的...这本书不仅提供了清晰的指导,还激发了创意和乐趣,使得反射的学习过程既富有成效又充满乐趣。

    Manning Java Reflection In Action

    无论是对于初学者还是有经验的开发者来说,本书都是学习和掌握Java反射技术不可或缺的宝贵资源。通过阅读本书,不仅可以提高对Java反射的理解,还能激发新的创意和灵感,将反射技术应用于更多创新的场景之中。

    Manning - Java Reflection in Action

    通过阅读《Java Reflection in Action》,开发者不仅可以了解到Java反射技术的基本原理和应用场景,还能学习到如何在实践中高效地运用这一强大工具。无论是对于初学者还是经验丰富的开发人员来说,这本书都是一个...

    High performance Java reflection.zip

    在"High performance Java reflection.zip"这个压缩包中,我们可以期待找到关于优化Java反射性能的相关资料,特别是可能涉及的库"reflectasm-master"。 ReflectASM是一个轻量级、高性能的Java反射库,旨在提高反射...

    浙大软件学院培训课件java reflection annotation

    Java反射(Reflection)和注解...学习和掌握这两者,对于提升Java开发者的技能水平和解决复杂问题的能力至关重要。通过“浙大软件学院”的培训课件,开发者可以深入理解这两个特性,并学会在实际项目中有效运用。

    Java Reflection In Action 源代码

    在《Java Reflection In Action》一书中,作者深入探讨了这一主题,提供了丰富的示例和源代码来帮助读者理解并熟练运用反射机制。这本书的源代码包含在名为"JRIA_listings"的压缩包中,为学习和实践反射提供了一个...

    java reflection demo

    Java反射是Java编程语言中的一个强大特性...在这个"java reflection demo"中,我们学习了如何动态加载外部JAR包,以及如何通过反射来调用类中的方法,这些都是Java开发中的重要技能,特别是在设计可扩展和动态系统时。

    JAVA 私塾笔记整理——反射机制(Reflection)

    在"JAVA私塾笔记整理——反射机制(Reflection)"这份文档中,我们将深入探讨反射机制的基础知识、用途和实现方式。 1. **反射机制的基本概念** 反射机制是Java提供的一种能够在运行时分析类和对象的能力。它允许...

Global site tag (gtag.js) - Google Analytics