JAVA SE 基础复习-Class与反射(2)

Java动态代理一——动态类Proxy的使用

更详细的参考:http://blog.csdn.net/lovelion/article/details/8116704

1.什么是动态代理?

答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实。代理一般会实现它所表示的实际对象的接口。代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功能,代理对象对客户隐藏了实际对象。客户不知道它是与代理打交道还是与实际对象打交道。
2.为什么使用动态代理?

答:因为动态代理可以对请求进行任何处理

3.使用它有哪些好处?

答:因为动态代理可以对请求进行任何处理
4.哪些地方需要动态代理?

答:不允许直接访问某些类;对访问要做特殊处理等

目前Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。 其实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。

Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现

以下为模拟案例,通过动态代理实现在方法调用前后向控制台输出两句字符串

目录结构

定义一个HelloWorld接口

package com.ljq.test;

 /**
 * 定义一个HelloWorld接口
 *
 * @author jiqinlin
 *
 */
 public interface HelloWorld {
    public void sayHelloWorld();
}

类HelloWorldImpl是HelloWorld接口的实现

package com.ljq.test;

 /**
 * 类HelloWorldImpl是HelloWorld接口的实现
 *
 * @author jiqinlin
 *
 */
 public class HelloWorldImpl implements HelloWorld{

    public void sayHelloWorld() {
        System.out.println("HelloWorld!");
    }

}

HelloWorldHandler是 InvocationHandler接口实现

package com.ljq.test;

 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;

 /**
 * 实现在方法调用前后向控制台输出两句字符串
 *
 * @author jiqinlin
 *
 */
 public class HelloWorldHandler implements InvocationHandler{
    //要代理的原始对象
     private Object obj;

    public HelloWorldHandler(Object obj) {
        super();
        this.obj = obj;
    }

    /**
     * 在代理实例上处理方法调用并返回结果
     *
     * @param proxy 代理类
     * @param method 被代理的方法
     * @param args 该方法的参数数组
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        //调用之前
         doBefore();
        //调用原始对象的方法
        result=method.invoke(obj, args);
        //调用之后
        doAfter();
        return result;
    }

    private void doBefore(){
        System.out.println("before method invoke");
    }

    private void doAfter(){
        System.out.println("after method invoke");
    }

}

测试类

package com.ljq.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class HelloWorldTest {

    public static void main(String[] args) {
        HelloWorld helloWorld=new HelloWorldImpl();
        InvocationHandler handler=new HelloWorldHandler(helloWorld);

        //创建动态代理对象
        HelloWorld proxy=(HelloWorld)Proxy.newProxyInstance(
                helloWorld.getClass().getClassLoader(),
                helloWorld.getClass().getInterfaces(),
                handler);
        proxy.sayHelloWorld();
    }
}

运行结果为:

时间: 2024-10-22 07:56:37

JAVA SE 基础复习-Class与反射(2)的相关文章

JAVA SE 基础复习-Class与反射

Class 关于Class,直接参考http://lavasoft.blog.51cto.com/62575/15433 Java程序在运行时,Java运行时系统一直对所有的对象进行所谓的运行时类型标识.这项信息纪录了每个对象所属的类.虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类.Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建.      Class 没有公共构造方法.Class 对象是在加载类时由 Java 虚拟机

Java SE 基础复习-内存泄露

一.Java内存回收机制 不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址.Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的.GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请.引用.被引用.赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环的问题.在J

java SE 基础复习-数组

数组 数组(Array):相同类型数据的集合. 定义数组 方式1(推荐,更能表明数组类型) type[] 变量名 = new type[数组中元素的个数]; 比如: int[] a = new int[10]; 数组名,也即引用a,指向数组元素的首地址. 方式2(同C语言) type变量名[] = new type[数组中元素的个数]; 如: int a[] = new int[10]; 方式3 定义时直接初始化 type[] 变量名 = new type[]{逗号分隔的初始化值}; 其中红色部

JAVA SE 基础复习-基本程序设计(1)

1.java基本数据类型 int         4      最大值 0x7fffffff 2147483647=2的31次方-1  首位为符号位   最小值-2147483648  0x80000000  补码存储 首位不变 其他位取反后加1 short     2      最大值2^15-1  32767  最小值-2^15  -32768 long       8     最大值2^63-1    最小值-2^63 byte       1     最大值2^7-1  127  最小值

JAVA SE 基础复习-基本程序设计(2)

3.java 运算符 单目乘除为关系,逻辑三目后赋值. 单目:单目运算符+ –(负数) ++ -- ! 等 乘除:算数单目运算符* / % + - 为:位移单目运算符<< >> 关系:关系单目运算符> < >= <= == != 逻辑:逻辑单目运算符&& || & | ^ 三目:三目单目运算符A > B ? X : Y 后:无意义,仅仅为了凑字数 赋值:赋值= 比如 1&2 ==3   先运算2==3   再与1并  

JAVA SE 基础复习-核心库-Collection---java.util

前言 花了点时间对照着JDK1.6树结构 ,做了下面这张图,以后复习方便多了. 图中椭圆形的是接口,棕色的长方形是抽象类,蓝色的长方形是普通类:红色线条是实现的接口.

JAVA SE 基础复习-前言

前言 准备找工作了,需要对JAVA只是进行总结,共八个部分: 一.JAVA基本程序设计 二.数组 三.面向对象编程 四.并发编程 五.IO 六.网络通信 七.泛型在面向对象中的应用 八.内存模型与虚拟机 九.JAVA核心库需要掌握的类.方法及联系 十.JAVA版本更新与其他

JAVA SE 基础复习-核心库-Map---java.util

Map Map框图如下 需要线程安全的情况使用ConcurrentHashMap. 遍历HashMap的方法,先获得遍历器   Iterator<Map.Entry<K,V>> iterator=map.entrySet().iterator();   然后  进行遍历.

Java SE 基础:标识(zh&#236;)符

Java SE 基础:标识(zhì)符 一.标识符定义 标识符,就是给类.接口.方法.变量等起名字时的字符序列 二.组成规则与注意事项 1.组成规则 英文大小写字母 数组 $ 和 _ 2.注意事项 不能以数组开头 不能是 Java 关键字(见关键字表:) 书写时区分大小写(大写和小写表示两个不同的标识符,如 public 和 Public 是不同的) 三.Java 中标识符的命名规则要做到:见名知意 包(package):包其实就是文件夹,用于区分项目中文件的结构,包名应当使用小写 单级包:to