Java反射机制的简单学习

今天看了一下Java的反射机制,就此记录一下。

首先,我们要先了解一下什么是反射?

  •   反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
  •   JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

Java反射的应用

  •   Spring框架 
  •   Hibernate框架:关联映射等
  •   白盒测试   

Java反射相关API

  java.lang包下

    -Class<T>:表示一个正在运行的 Java 应用程序中的类和接口,是Reflection的起源

  java.lang.reflect包下

    -Field 类:代表类的成员变量(也称类的属性)

    -Method 类 : 代表类的方法

    -Array 类 : 提供了动态创建数组,以及访问数组的元素的静态方法

反射的类类型:Class

假设我们有一个Role类

 1 package _Venom_.reflection;
 2 
 3 public class Role {
 4     
 5     private String name;
 6     private String type;
 7     
 8     //Constructors
 9     public Role(){
10         System.out.println("Constructor Role() is invoking!");
11     }
12     
13     private Role(String _name){
14         this.name = _name;
15         System.out.println("Constructor Role(String _name) is invoking!");
16     }
17 
18     
19     //get and set method
20     public String getName() {
21         return name;
22     }
23 
24     public void setName(String name) {
25         this.name = name;
26     }
27 
28     public String getType() {
29         return type;
30     }
31 
32     public void setType(String type) {
33         this.type = type;
34     }
35 
36     //override the toString method to show the class
37     @Override
38     public String toString() {
39         // TODO Auto-generated method stub
40         return "This is a role called " + this.name;
41     }
42     
43 }

我们可以通过以下方式得到类类型。

获取方式

说明

示例

object.getClass()

每个对象都有此方法

获取指定实例对象的Class

List list = new ArrayList();

Class listClass = list.getClass();

class. getSuperclass()

获取当前Class的继承类Class

List list = new ArrayList();

Class listClass = list.getClass();

Class superClass = listClass. getSuperclass();

Object.class

.class直接获取

Class listClass = ArrayList.class;

Class.forName(类名)

用Class的静态方法,传入类的全称即可

try {

Class c = Class.forName("java.util.ArrayList");

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

Primitive.TYPE

基本数据类型的封装类获取Class的方式

Class longClass = Long.TYPE;

Class integerClass = Integer.TYPE;

Class voidClass = Void.TYPE;


Class class1 = Role.class; try { Class class2 = Class.forName("_Venom_.reflection.Role"); } catch (ClassNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }

通过类类型的newInstance方法来创建一个实例。如下

Object obj = class1.newInstance();

但是,我们通常的做法是通过Constructor类来获取类的构造方法,然后再通过Constructor类的newInstance方法来创建实例。

获取类的构造器

Constructor类:

  •   public Constructor<?>[] getConstructor()   返回类中的所有public构造器集合,默认构造器的下标为0
  •   public Constructor<T> getConstructor(Class<?>...parameterTypes) 返回指定的public构造器,参数为构造器参数类型集合
  •      public  Constructor<?>[] getDeclaredConstructor() 返回类中所有的构造器,包括私有
  • public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes) 返回任意指定的构造器
Class class1 = Role.class;
        try {
            Class class2 = Class.forName("_Venom_.reflection.Role");
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        
        /**
         * 获取构造方法Constructor
         * getConstructor() only for public 
         * getDeclaredConstructor() global access all
         * */
        Constructor constructor = null;
        //指定参数列表获取特定的方法
        try {
       //1 constructor
= class1.getDeclaredConstructor(new Class[]{String.class}); //设置可访问的权限 不设置会报IllegalAccessException异常 constructor.setAccessible(true); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } Object obj = null; try { obj = constructor.newInstance(new Object[]{"Venom"}); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } //打印对象的信息 System.out.println(obj); //2获取所有的构造方法的集合 Constructor constructorArr[] = null; constructorArr = class1.getDeclaredConstructors(); constructorArr[1].setAccessible(true); Object obj1 = null; try { obj1 = constructorArr[1].newInstance(new Object[]{"_Venom_"}); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(obj1);
解释一下:第一个是获得一个指定的方法,我们指定了参数是一个String类型,第二段我们获得了所有的构造方法集合,并选取了其中一个创建了新的对象。
  当我们获得私有的方法的时候,要用setAccessible设置一下可访问的权限。
以此类推:
  在获取类的成员变量的时候,我们可以使用Field类
    主要的方法非常的类似:
    • public Field getDeclaredField(String name)  获取任意指定名字的成员
    • public Field[] getDeclaredFields()             获取所有的成员变量
    • public Field getField(String name)           获取任意public成员变量
    • public Field[] getFields()                          获取所有的public成员变量

  在获取类的方法的时候,我们可以使用Method类:

     
    • public Method[] getMethods()    获取所有的共有方法的集合
    • public Method getMethod(String name,Class<?>... parameterTypes) 获取指定公有方法 参数1:方法名 参数2:参数类型集合  
    • public Method[] getDeclaredMethods()  获取所有的方法
    • public Method getDeclaredMethod(String name,Class<?>... parameterTypes) 获取任意指定方法

总结:

  感觉今天学习的Java反射机制还是很有用出的,以此Mark一下我的学习历程。

    

posted @ 2013-08-25 13:31  _Venom_  阅读(289)  评论(0编辑  收藏  举报