java 反射和内省

1       反射和内省

反射 (Reflection) JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为 java 语言的反射机制。
内省 (Introspector) ,是“看透 class ”的能力(内省、内观、反省)。
2.1    “Class” object的取得途径
Java 允许我们从多种管道为一个 class 生成对应的 Class object

Class object 诞生管道
示例
运用 getClass()
注:每个 class 都有此函数
String str = "abc";
Class c1 = str.getClass();
运用
Class.getSuperclass() 2
Button b = new Button();
Class c1 = b.getClass();
Class c2 = c1.getSuperclass();
运用 static method
Class.forName()
(最常被使用)
Class c1 = Class.forName ("java.lang.String");
Class c2 = Class.forName ("java.awt.Button");
Class c3 = Class.forName ("java.util.LinkedList$Entry");
Class c4 = Class.forName ("I");
Class c5 = Class.forName ("[I");
运用
.class 语法
Class c1 = String.class;
Class c2 = java.awt.Button.class;
Class c3 = Main.InnerClass.class;
Class c4 = int.class;
Class c5 = int[].class;
运用
primitive wrapper classes
TYPE 语法
 
Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Character.TYPE;
Class c4 = Short.TYPE;
Class c5 = Integer.TYPE;
Class c6 = Long.TYPE;
Class c7 = Float.TYPE;
Class c8 = Double.TYPE;
Class c9 = Void.TYPE;

1 Java 允许多种管道生成 Class object
 
以图 2 java.util.LinkedList 为例,将 Java class 的定义大卸八块,每一块分别对应图 3 所示的 Reflection API
 
package java.util;                 //(1)
import java.lang.*;                //(2)
public class LinkedList < E >              //(3)(4)(5)
extends AbstractSequentialList <E>               //(6)
implements List <E>, Queue <E>,
Cloneable, java.io.Serializable              //(7)
{
private static class Entry <E> { }//(8)
public LinkedList () { }                  //(9)
public LinkedList (Collection<? extends E> c) { }
public E getFirst () { }                  //(10)
public E getLast () { }
private transient Entry<E> header = ;        //(11)
private transient int size = 0;
}
2 :将一个 Java class 大卸八块,每块相应于一个或一组 Reflection APIs (图 3 )。
 
2.3    Java classes 各成份所对应的Reflection APIs
2 的各个 Java class 成份,分别对应于图 3 Reflection API ,其中出现的 Package Method Constructor Field 等等 classes ,都定义于 java.lang.reflect 。本表并非 Reflection APIs 的全部。

Java class 内部模块(参见 3
Java class 内部模块说明
相应之 Reflection API ,多半为 Class methods
返回值类型 (return type)
(1) package
class 隶属哪个 package
getPackage()
Package
(2) import
class 导入哪些 classes
无直接对应之 API
解决办法见 5-2
 
(3) modifier
class (或 methods, fields )的属性
 
int getModifiers()
Modifier.toString(int)
Modifier.isInterface(int)
int
String
bool
(4) class name or interface name
class/interface
名称 getName()
String
(5) type parameters
参数化类型的名称
getTypeParameters()
TypeVariable <Class>[]
(6) base class
base class (只可能一个)
getSuperClass()
Class
(7) implemented interfaces
实现有哪些 interfaces
getInterfaces()
Class[]
 
(8) inner classes
内部 classes
getDeclaredClasses()
Class[]
(8') outer class
如果我们观察的 class 本身是 inner classes ,那么相对它就会有个 outer class
getDeclaringClass()
Class
(9) constructors
构造函数 getDeclaredConstructors()
不论 public private 或其它 access level ,皆可获得。另有功能近似之取得函数。
Constructor[]
(10) methods
操作函数 getDeclaredMethods()
不论 public private 或其它 access level ,皆可获得。另有功能近似之取得函数。
Method[]
(11) fields
字段(成员变量)
getDeclaredFields() 不论 public private 或其它 access level ,皆可获得。另有功能近似之取得函数。
Field[]

3 Java class 大卸八块后(如图 2 ),每一块所对应的 Reflection API
Model.java
 
package RefInt;
 
import java.io.Serializable;
import java.util.Date;
 
public class Model implements Serializable {
 
    private static final long serialVersionUID = -162798607158235676L;
 
    public static String id = "111111" ;
    public String name = "haha" ;
    private int age ;
    private Date b ;
   
    public int getAge() {
       return age ;
    }
    public void setAge( int age) {
       this . age = age;
    }
    public Date getB() {
       return b ;
    }
    public void setB(Date b) {
       this . b = b;
    }
    public String getName() {
       return name ;
    }
    public void setName(String name) {
       this . name = name;
    }
}
RefInt.java
 
package RefInt;
 
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
 
public class RefInt {
   
    public static void main(String[] args) {
       System. out .println( "f_1()" );
       f_1();
       System. out .println( "f_2()" );
       f_2();
       System. out .println( "f_3()" );
       f_3();
       System. out .println( "f_4()" );
       f_4();
       System. out .println( "getArrayByIndex()" );
       int [] a = {10,2,3,5};
       String[] s = { "aabc" , "aaabc" , "def" , "f" };
       // 数组排序
       Arrays.sort(s);
       System. out .println(getArrayByIndex(s,0));
       System. out .println(getArrayByIndex(a,0));
       System. out .println(getArrayByIndex(a,3));
       Arrays.sort(a);
       System. out .println(getArrayByIndex(a,0));
       System. out .println(getArrayByIndex(a,3));
       Array.set(a, 0, -1);
       System. out .println(getArrayByIndex(a,0));
    }
 
    /**
      * 获得数组 o 下标为 index 的值
      * @param o
      * @param index
      * @return
      */
    public static Object getArrayByIndex(Object o , int index) {
       return Array.get(o, index);
    }
   
    /**
      * 通过类名得到类描述对象
      * 通过类描述对象获得类模式(此类为 public
      */
    public static void f_4() {
       try {
           Class class_my = Class.forName( "RefInt.Model" );
           int m = class_my.getModifiers();
           System. out .println(class_my.getModifiers());
           if (Modifier.isPublic(m))
                System. out .println( "public" );
 
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       } catch (SecurityException e) {
           e.printStackTrace();
       } catch (IllegalArgumentException e) {
           e.printStackTrace();
       }
    }
   
    /**
      * 通过类名得到类描述对象
      * 通过类描述对象获得属性对象列表并显示其属性
      */
    public static void f_3() {
       try {
           Class class_my = Class.forName( "RefInt.Model" );
           // 只能得到属性是 public Field
           Field[] publicFields = class_my.getFields();
           for ( int i = 0; i < publicFields. length ; i++) {
              String fieldName = publicFields[i].getName();
              Class typeClass = publicFields[i].getType();
              String fieldType = typeClass.getName();
              System. out .println( "Name: " + fieldName + ", Type: " + fieldType);
           }
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       }
    }
    /**
      * 通过实体对象获得类描述对象
      * 通过累描述对象获得指定属性对象
      * 通过属性对象实例得到属性名和属性值
      */
    public static void f_2() {
       Model model = new Model();
       // 属性必须是 public, 否则抛出 NoSuchFieldException 异常
       String sfiled = "name" ;
       Class class_my = model.getClass();
       try {
           Field filed = class_my.getField(sfiled);
           System. out .println(filed.getName());
           System. out .println(filed.get(model));
       } catch (SecurityException e) {
           e.printStackTrace();
       } catch (NoSuchFieldException e) {
           e.printStackTrace();
       } catch (IllegalArgumentException e) {
           e.printStackTrace();
       } catch (IllegalAccessException e) {
           e.printStackTrace();
       }
    }
   
    /**
      * 通过类名获得实体对象
      * 通过属性名称获取实体对象属性值
      */
    public static void f_1() {
       try {
           Class cla = Class.forName( "RefInt.Model" );
           Object o = cla.newInstance();
           String methodName = "getName" ;
           Method m = cla.getMethod(methodName, (Class[]) null );
           System. out .println(m.invoke(o, (Object[]) null ));
           methodName = "getAge" ;
           m = cla.getMethod(methodName, (Class[]) null );
           System. out .println(m.invoke(o, (Object[]) null ));
           methodName = "getB" ;
           m = cla.getMethod(methodName, (Class[]) null );
           System. out .println(m.invoke(o, (Object[]) null ));
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       } catch (InstantiationException e) {
           e.printStackTrace();
       } catch (IllegalAccessException e) {
           e.printStackTrace();
       } catch (SecurityException e) {
           e.printStackTrace();
       } catch (NoSuchMethodException e) {
           e.printStackTrace();
       } catch (IllegalArgumentException e) {
           e.printStackTrace();
       } catch (InvocationTargetException e) {
           e.printStackTrace();
       }
    }
}
 
一般的做法是通过类 Introspector 来获取某个对象的 BeanInfo 信息,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后我们就可以通过反射机制来调用这些方法。
Intro.java
 
package RefInt;
 
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
 
public class Intro {
    public static void main(String[] args) {
       Model m = new Model();
       try {
           // 从其所在位置开始停止分析的基类。 stopClass 或其基类中的所有方法 / 属性 / 事件都将在分析中被忽略。
           BeanInfo beanInfor = Introspector.getBeanInfo(m.getClass(),Object. class );
           PropertyDescriptor[] p = beanInfor.getPropertyDescriptors();
           for ( int i=0;i<p. length ;i++){
              System. out .println(p[i].getName()+ "=" +
                      p[i].getReadMethod().invoke(m,(Object[]) null ));
            }
 
       } catch (IntrospectionException e) {
           e.printStackTrace();
       } catch (IllegalArgumentException e) {
           e.printStackTrace();
       } catch (IllegalAccessException e) {
           e.printStackTrace();
       } catch (InvocationTargetException e) {
           e.printStackTrace();
       }
    }
}
 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值