码迷,mamicode.com
首页 > 编程语言 > 详细

Java的反射与代理

时间:2018-01-28 17:25:49      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:动态获取   注意   运行   静态   ceo   实现   设计   好用   目标   

java的类型信息在运行时如何表示?

    通过Class对象,class类是程序运行期间,为所有的对象维护一个运行时的类型标识,保存这些信息的类被称为class。

    如何获取类的class对象引用?

        1. Class.forName();forname是class类的静态方法。

        2. 如果已经有一个对象,可以调用对象的getClass(),此方法属于根类object。

        3. 使用类字面常量.class;不仅可以用于普通的类,还可以用于接口,数组,以及基本数据类型。

      注意,一个class对象表示一个类型,未必一定是一种类。如Class c = int.class,c不是类,但是一个class类型对象。

    .class和forName()的区别:

        程序中每一个类都有一个class对象,所有的类都是在对其第一次使用时,动态加载到JVM中。当程序创建第一个对类的静态成员的引用时(构造器也是类的静态方法),就会加载这个类,然后进行类的静态初始化。通过.class得到class对象引用,不会触发类的初始化,而使用forName()会使类进行初始化。

    Class类是泛型的。我们可以用泛型语法,让编译器进行额外的类型检查。

        如 Class<?> intClass = int.class;    Class<House> houseType = House.class;

    我们可以根据得到的class引用,判断一个对象obj是不是某个Class类型的实例(如类名为Base)。

        1. obj instanceof Base

        2. Base.class.isInstance(obj)

    instanceof 和insInstance都保持了类型的概念,即可以识别出继承的关系。

    

若我们想要在运行时获取类的信息呢?在编译时不能确定需要的是哪个类,所以.class和getClass()是显然不好用的。

Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

Class类与java.lang.reflect类库一起对反射的概念进行了支持。

在Class类中:

    Static Class forName(String className)可以得到该类型的对象引用

    Object newInstance()创建该类型实例

    默认使用类的无参数构造器,如果创建有参数实例,需要先调用getConstructors(),得到一个Constructor构造器的实例。

        Eg.e.getClass().newInstance()    e.getConstructor(String.class).newInstance(“233”)

    Field[] getFields()

    Method[] getMethods()

    Constructor[] getConstructors()

java.lang.reflect类库中有三个类:
    Field:描述类的域

    Method:描述类的方法

    Constructor:描述类的构造器

在method类中:

Public Object invoke(Object implicitPara,Object[] explicitPara) 调用任意方法。

通过这些类库中类的方法可以实现动态获取类型信息。


代理是基本的设计模式之一,代理通常充当着中间人的身份。一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

静态代理:写在代码里,通过中间类去操作实际类,也就是被代理的类

动态代理:动态地创建代理,动态地实现对实际类的调用。

 

反射和java.lang.reflect.Proxy等相关类实现了动态代理。

动态代理分为3个步骤:

    1. 建立委托类,即被代理的类,创建Interface接口和实现类;

    2. 创建实现了InvocationHandler接口的代理类,在invoke()内执行代理操作;

    3. 创建代理对象,将代理对象传递给调用者。

通过调用proxy的静态方法newProxyInstance()创建动态代理,

static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

这个方法需要三个参数:

    1. ClassLoader loader指明生成代理对象使用的类装载器

    2. Class<?>[] interfaces指定代理器实现的接口列表

    3. InvocationHandler h指明Invocation接口的一个实现,就是定义的代理类要做的事情。

通过动态代理,不管调用代理对象的什么方法,都是调用代理器的invoke方法,在这里人为地决定了如何调用被代理对象的原始方法,如何进行额外的处理。相当于对被代理对象直接方法调用的拦截。


Java的反射与代理

标签:动态获取   注意   运行   静态   ceo   实现   设计   好用   目标   

原文地址:http://blog.51cto.com/13580976/2066008

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!