译作:《Core Java2 7e》之 Reflection

 

Reflection

1 介绍Class对象

一个Class对象描述一个类或原始的数据类型。每个类一开始加载时,都会创建一个Class对象,代表着它的类型信息。

 虚拟机为每个类型管理着一个独一无二的Class对象。

 

 

  有三种方法获得类的Class对象。

  1Class cl1 = Date.class; // if you import java.util.*;
    
    
Class cl2 = int.class;
   
   
Class cl3 = Double[].class;
   
   
2String className = "java.util.Date";
    
    
Class cl = Class.forName(className);
   
   

   如果指定的类不存在,抛出ClassNotFoundException异常

 3Employee e;
. . .
Class cl = e.getClass();

    使用类的对象的getClass()方法。

 

 

   Class的方法getName()可以获得类的名字。

由于历史的原因,对于数组来说,class对象的getName() 方法将返回一个古怪的字符串:

·         Double[].class.getName() returns "[Ljava.lang.Double;".

·         int[].class.getName() returns "[I".

 

 

  虚拟机里每个类型(类或原始数据类型等)对应着一个独一无二的Class对象来表示它的类型信息,所以可以用以下方法比较2个对象所属的类是否一样:

   if ( e.getClass() = = Employee.class)… …

API:

java.lang.Class 1.0

 

  • static Class forName(String className)

returns the Class object representing the class with name className.

  • Object newInstance()

returns a new instance of this class.

 

2 使用反射机制分析类的结构

  Using Reflection to Analyze the Capabilities of Classes

 

在包java.lang.reflect里,有三个类用来描述属性、方法、构造函数,分别为:FieldMethodConstructor.

Field类有getName()方法可以获得属性的名字,getType()方法返回一个Class对象,描述属性的数据类型。

MethodConstructor含有可以获得参数类型的方法,Method还有可以获得函数返回值类型的方法。

3个类都含有getModifiers()的方法,用来获得修饰符(static,private,public,final等等这些),它返回一个整数,Modifier类含有多个静态方法对这个整数分析。例如:

isPublic, isPrivate, or isFinal ,来判断是否public,privatefinal。可以使用Modifierd.toString(int )方法返回修饰符的串。

 

 

 

ClassgetFields, getMethods, and getConstructors方法的返回值是数组,分别是被分析类及其父类(即是整个继承树上的类)的public的属性、方法、构造函数的FieldMethodConstructor数组。

getdeclaredFields, getDeclaredMethods, and getDeclaredConstructors 方法返回的是被分析类(不包括父类)的所有属性、方法、构造函数的FieldMethodConstructor数组,包括public的、private的、protected的等。

 

 

 

API

java.lang.Class 1.0

  • Field[] getFields() 1.1
  • Field[] getDeclaredFields() 1.1

The getFields method returns an array containing Field objects for the public fields of this class or its superclasses. The geTDeclaredField method returns an array of Field objects for all fields of this class. The methods return an array of length 0 if there are no such fields or if the Class object represents a primitive or array type.

  • Method[] getMethods() 1.1
  • Method[] getDeclaredMethods() 1.1

return an array containing Method objects: getMethods returns public methods and includes inherited methods; getdeclaredMethods returns all methods of this class or interface but does not include inherited methods.

  • Constructor[] getConstructors() 1.1
  • Constructor[] getDeclaredConstructors() 1.1

return an array containing Constructor objects that give you all the public constructors (for getConstructors) or all constructors (for getdeclaredConstructors) of the class represented by this Class object.

 

java.lang.reflect.Constructor 1.1

  • Class getDeclaringClass()

returns the Class object for the class that defines this constructor, method, or field.

  • Class[] getExceptionTypes() (in Constructor and Method classes)

returns an array of Class objects that represent the types of the exceptions thrown by the method.

  • int getModifiers()

returns an integer that describes the modifiers of this constructor, method, or field. Use the methods in the Modifier class to analyze the return value.

  • String getName()

returns a string that is the name of the constructor, method, or field.

  • Class[] getParameterTypes() (in Constructor and Method classes)

returns an array of Class objects that represent the types of the parameters.

  • Class getReturnType() (in Method classes)

returns a Class object that represents the return type.

 

java.lang.reflect.Modifier 1.1

  • static String toString(int modifiers)

returns a string with the modifiers that correspond to the bits set in modifiers.

  • static boolean isAbstract(int modifiers)
  • static boolean isFinal(int modifiers)
  • static boolean isInterface(int modifiers)
  • static boolean isNative(int modifiers)
  • static boolean isPrivate(int modifiers)
  • static boolean isProtected(int modifiers)
  • static boolean isPublic(int modifiers)
  • static boolean isStatic(int modifiers)
  • static boolean isStrict(int modifiers)
  • static boolean isSynchronized(int modifiers)
  • static boolean isVolatile(int modifiers)

These methods test the bit in the modifiers value that corresponds to the modifier in the method name.

 

 

3使用反射在RunTime分析对象

Using Reflection to Analyze Objects at Run Time

 

 

在运行时分析对象的具体内容,例如属性的值。

 

先看一个例子:

Employee harry = new Employee("Harry Hacker", 35000, 10, 1, 1989);
   
   

  
  
   
    
  
  
// the class object representing Employee
   
   
Class cl = harry.getClass();
   
   
// the name field of the Employee class
   
   
Field f = cl.getDeclaredField("name");
   
   
// the value of the name field of the harry object
   
   
// i.e., the String object "Harry Hacker"   
   
   
Object v = f.get(harry);
   
   
 
   
   

但是,这个例子存在一个问题,由于name属性是private的,所以会抛出IllegalAccessException异常。你只能够使用Fieldget方法去访问那些有访问权限的属性。

Java的安全机制可以允许你获知对象的拥有哪些属性,但不允许你获得它们的属性值,除非你有访问的权限。
  Reflection
的默认守则是要尊重Java的安全机制,However, if a Java program is not controlled by a security manager that disallows it, you can override access control. To do this, invoke the setAccessible method on a Field, Method, or Constructor object.

  例如:

f.setAccessible(true); // now OK to call f.get(harry);
   
   

 

setAccessible是类AccessibleObject里定义的方法,它是FieldMethodConstructor的父类。

 

Fieldget()方法返回一个对象,如果属性的数据类型是原始类型,则返回的是它们的包装类。或者可以使用getDouble等方法获取原始数据类型值。

 

同样,你同样可以使用set方法为某个对象的属性设置值。f.set(obj,value).

 

 

4方法的指针

Method Pointers!

表面上,Java不提供方法指针,Java的设计者们强调方法指针是危险的和易于引发错误。

然而,JDK1.1已经含有了方法指针,它是reflection package的副产品。

 

Method类提供了invoke方法去调用被分析对象的方法:
    
    
Object invoke(Object obj, Object... args)
   
   

第一个参数是被分析对象,后面的参数是调用被分析对象方法的输入参数(在JDK5.0以前,后面的参数采用一个数组表示,如果没有被分析对象的调用方法输入参数,则传入null)。

如果调用的是一个静态方法,则第一个参数被忽略,你可以传入null

 

可以通过Class类的getMethods方法获取Method数组,还可以以下这种方法:

  JDK 5.0

Method getMethod(String name, Class... parameterTypes)

 第一个参数为方法名,后面的参数为方法的输入参数,通过这样的方式去定位到被分析类的某个方法。

 For example, here is how you can get method pointers to the getName and raiseSalary methods of the Employee class

Method m1 = Employee.class.getMethod("getName");

Method m2 = Employee.class.getMethod("raiseSalary", double.class);

 

(Before JDK 5.0, you had to package the Class objects into an array or to supply null if there were no parameters.)

 

 

 

 

API

java.lang.reflect.Method 1.1

  • public Object invoke(Object implicitParameter, Object[] explicitParameters)

invokes the method described by this object, passing the given parameters and returning the value that the method returns. For static methods, pass null as the implicit parameter. Pass primitive type values by using wrappers. Primitive type return values must be unwrapped.

 

 

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值