您的位置:首页 > 编程语言 > Java开发

Java反射机制学习笔记

2010-07-25 14:06 453 查看
1.Java反射机制的作用

在 Java 运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意

一个对象,能否调用它的任意一个方法?答案是肯定的。这种动态获取类的信息,以及动态

调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。Java 反射机制主要提供

了以下功能:

l 在运行时判断任意一个对象所属的类;

l 在运行时构造任意一个类的对象;

l 在运行时判断任意一个类所具有的成员变量和方法;

l 在运行时调用任意一个对象的方法;

l 生成动态代理。

本章首先介绍了Java Reflection API的用法,然后介绍了一个远程方法调用的例子,在

这个例子中客户端能够远程调用服务器端的一个对象的方法。服务器端采用了反射机制提供

的动态调用方法的功能,而客户端则采用了反射机制提供的动态代理功能

2.Java反射中所涉及的几个重要的类,这些类都位于java.lang.reflect包中

Class类:代表一个类,通过反射操作一个类,都需要需要根据指定的类创建一个Class对象

Method类:代表类中的方法,为了操作一个方法,java.lang.reflect提供了Method类,可以创建指定

方法的Method对象,这个对象就代表了这个方法,这也体现了一切都是对象的思想。

Field类:代表类的成员变量

Constructor类:代表类的构造方法,这里不解析,因为都可以像Method类一样理解

Array类:用于动态创建数组,以及访问数组元素

3
.使用java.lang.reflect包中的类的三个步骤

1.获得一个java.lang.Class对象,这个对象是通过指定你要操作的类而获得。java.lang.Class在运 行的java程序被用作代表类和接口(

The first step is to obtain a
java.lang.Class


object for the class that you want to manipulate.
java.lang.Class


is used to represent classes and interfaces in a running Java program.
)。

获得java.lang.Class对象由三种方法:

One way of obtaining a Class object is to say:
Class c = Class.forName("java.lang.String");
to get the Class object for String
Another approach is to use:
Class c = int.class;
or
Class c = Integer.TYPE;


2.获得类信息,例如method、field、constructor(The second step is to call a method such as [code]getDeclaredMethods


,
to get a list of all the methods declared by the class.
)。

[/code]


3.获得信息后,利用反射机制的API操作这些信息(Once this information is in hand, then the third step is to use the
reflection API to manipulate the information. For example)。



4.对Method类中的invoke方法的理解

Method (Java 2 Platform SE 6)



invoke
public Objectinvoke(Object obj, Object ... args) throws IllegalAccessException
, IllegalArgumentException
,InvocationTargetException


对带有指定参数的指定对象调用由此 [code]Method


对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,基本参数和引用参数都随需服从方法调用转换。

[/code]

如果底层方法是静态的,那么可以忽略指定的
obj

参数。该参数可以为 null。

如果底层方法所需的形参数为 0,则所提供的
args

数组长度可以为 0 或 null。

如果底层方法是实例方法,则使用动态方法查找来调用它,这一点记录在 Java Language Specification, Second Edition
的第 15.12.4.4 节中;在发生基于目标对象的运行时类型的重写时更应该这样做。

如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。

如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。但是,如果该值的类型为一组基本类型,则数组元素不

被包装在对象中;换句话说,将返回基本类型的数组。如果底层方法返回类型为 void,则该调用返回 null。



参数:

obj

- 从中调用底层方法的对象

args

- 用于方法调用的参数

返回:

使用参数
args

obj

上指派该对象所表示方法的结果

抛出:


IllegalAccessException


- 如果此
Method

对象强制执行 Java 语言访问控制,并且底层方法是不可访问的。

IllegalArgumentException


-
如果该方法是实例方法,且指定对象参数不是声明底层方法的类或接口(或其中的子类或实现程序)的实例;如果实参和形参的数量不相同;如果基本参数的解包转换失败;如果在解包后,无法通过方法调用转换将参数值转换为相应的形参类型。

InvocationTargetException


- 如果底层方法抛出异常。

NullPointerException


- 如果指定对象为 null,且该方法是一个实例方法。

ExceptionInInitializerError


- 如果由此方法引起的初始化失败。

对该方法的理解我们来看一个具体的例子:

  import java.lang.reflect.*;
     public class method2 {
      public int add(int a, int b)
      {
         return a + b;
      }
      public static void main(String args[])
      {
         try {
           Class cls = Class.forName("method2");
           Class partypes[] = new Class[2];
            partypes[0] = Integer.TYPE;
            partypes[1] = Integer.TYPE;
            Method meth = cls.getMethod(
              "add", partypes);(1)
            method2 methobj = new method2();(2)
            Object arglist[] = new Object[2];
            arglist[0] = new Integer(37);
            arglist[1] = new Integer(47);
            Object retobj 
              = meth.invoke(methobj, arglist);(3)
            Integer retval = (Integer)retobj;
            System.out.println(retval.intValue());
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }






(1)处创建了一个指定方法的对象,(2)处调用该对象表示的底层方法


在这里要有一个思维的变换,我们在(2)处创建了一个method2的对象,按照我们的习惯,调用某某方法都是methobj.xx()这样调用,但是用到反射之后我们就不能这么调用了,而是把此对象当成一个参数了。
首先来看对invoke方法的解释:对带有指定参数的指定对象调用由此
Method


对象表示的底层方法。
分析:Object retobj=meth.invoke(methobj,arglist);
这句话的结果就是调用了add方法,但是不知直接调用的,“带有指定参数的指定对象”这里指的就是methOject和arglist,“此Method对象”表示的就是meth。这里调用方法转了一个弯,总而言之我们在用到此方法时一定要把思维转过来,这个时候我们不再需要手动去指定调用方法,而是通过传入主体对象和参数,然后程序会自动帮助我们调用要调用的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: