天天看点

黑马程序员_java学习笔记之代理类

------- android培训、java培训、期待与您交流! ----------

张孝祥老师代理类讲解之总结 ?

package com.itheima;

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.ArrayList;

import java.util.Collection;

public

class

ProxyReview {

public

static

void

main(String[] args)throws Exception{

//public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces)  throws IllegalArgumentException

Class clazzProxy1=Proxy.getProxyClass(Collection.

class

.getClassLoader(), Collection.

class

);

//注在这里接口.class 文件是可变参数的,不是一个集合

//获取动态类的.class文件的名字

System.

out

.println(clazzProxy1.getName());

System.

out

.println(

""

);

//利用反射获取clazzProxy1中的非私有构造方法的数组

Constructor[] constructors=clazzProxy1.getConstructors();

//对构造函数进行遍历

for

(Constructor  constructor : constructors){

//创建一个字符串缓冲区

StringBuilder sb=

new

StringBuilder();

String name=constructor.getName();

sb.append(name);

sb.append(

"("

);

//对构造方法的参数列表进行遍历

Class[] clazzParams = constructor.getParameterTypes();

for

(Class clazzParam : clazzParams ){

sb.append(clazzParam.getName());

}

//因为添加到最后一个参数时也会有,所以在添加时需要删除最后一个,

if

(clazzParams!=

null

&&clazzParams.length!=0){

sb.deleteCharAt(clazzParams.length-1);

}

sb.append(

")"

);

System.

out

.println(sb.toString());

}

System.

out

.println(

""

);

//利用反射获取clazzProxy1中的非私有方法的数组

Method[] methods=clazzProxy1.getMethods();

//对方法进行遍历

for

(Method  method : methods){

//创建一个字符串缓冲区

StringBuilder sb=

new

StringBuilder();

String name=method.getName();

sb.append(name);

sb.append(

"("

);

//对非私有方法的参数列表进行遍历

//特别注意 在下面方法中 如果方法的没有参数则返回长度为0的数组  在遍历不会报空指针异常 

Class[] clazzParams = method.getParameterTypes();

for

(Class clazzParam : clazzParams ){

sb.append(clazzParam.getName());

}

//因为添加到最后一个参数时也会有,所以在添加时需要删除最后一个,

if

(clazzParams!=

null

&&clazzParams.length!=0){

sb.deleteCharAt(clazzParams.length-1);

}

sb.append(

")"

);

System.

out

.println(sb.toString());

}

//根据class文件创建一个动态类的对象

//

//首先得到生成对象的构造函数,通过构造函数创建对象

class

myInvocationHandler implements InvocationHandler{

//复写invoke方法

@Override

public

Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

// TODO Auto-generated method stub

return

null

;

}

}

Constructor constructor=clazzProxy1.getConstructor(InvocationHandler.

class

);

Collection collection = (Collection)constructor.newInstance(

new

myInvocationHandler());

//Proxy没有不带参数的构造方法所以给其穿个参数,参数类型为InvocationHandler是个借口,自己new一个myInvocationHandlerd对象

Collection colletion2 = (Collection)constructor.newInstance(

new

InvocationHandler(){

@Override

public

Object invoke(Object proxy, Method method,

Object[] args) throws Throwable {

// TODO Auto-generated method stub

return

null

;

}

}

);

Collection collection4 = (Collection)Proxy.newProxyInstance(Collection.

class

.getClassLoader(),

new

Class[]{Collection.

class

},

new

InvocationHandler(){

//定义一个目标类

ArrayList target=

new

ArrayList();

@Override

public

Object invoke(Object proxy, Method method,

Object[] args) throws Throwable {

// TODO Auto-generated method stub

Object retVal=method.invoke(target, args);

return

null

;

}

}

);

//调用动态类collection3的add方法 会报空指针异常,调用有返回值类型的方法都会报错

collection4.add(

"123"

);

System.

out

.println(collection4.size());

System.

out

.println(collection4);

Collection collection3 = (Collection)Proxy.newProxyInstance(Collection.

class

.getClassLoader(),

new

Class[]{Collection.

class

},

new

InvocationHandler(){

//定义一个目标类

ArrayList target=

new

ArrayList();

@Override

public

Object invoke(Object proxy, Method method,

Object[] args) throws Throwable {

// TODO Auto-generated method stub

//调用目标类的方法,并传参

Object retVal=method.invoke(target, args);

return

null

;

}

}

);

//调用动态类collection3的add方法 会报空指针异常,调用有返回值类型的方法都会报错

collection4.add(

"123"

);

System.

out

.println(collection4.size());

System.

out

.println(collection4);

//下面是用myeclipse完整的一段代码其中有用到公告

final ArrayList target=

new

ArrayList();

Collection collection5 = getProxy(target,

new

MyAdvice());

collection5.add(

"abc"

);

collection5.add(

"bcd"

);

collection5.add(

"bxd"

);

System.

out

.println(collection5.size());

}

//利用myeclipse将这两个对象抽成一个方法

private

static

Collection getProxy(final ArrayList target,final Advice advice) {

Collection collection5 = (Collection)Proxy.newProxyInstance(Collection.

class

.getClassLoader(),

new

Class[]{Collection.

class

},

new

InvocationHandler(){

//定义一个目标类

@Override

public

Object invoke(Object proxy, Method method,

Object[] args) throws Throwable {

// TODO Auto-generated method stub

//调用目标类的方法,并传参

advice.beforeMethod(method);

Object retVal=method.invoke(target, args);

advice.afterMethod(method);

return

null

;

}

}

);

return

collection5;

}

}

class

MyAdvice implements Advice {

long

startTime=0;

@Override

public

void

beforeMethod(Method method) {

// TODO Auto-generated method stub

System.

out

.println(

"我这是要开始"

);

startTime=System.currentTimeMillis();

}

@Override

public

void

afterMethod(Method method) {

// TODO Auto-generated method stub

System.

out

.println(

"我结束了"

);

long

endTime=System.currentTimeMillis();

System.

out

.println(method.getName()+

" running time is "

+(startTime-endTime));

}

}

interface

Advice {

public

abstract

void

beforeMethod(Method method);

public

abstract

void

afterMethod(Method method);

}

继续阅读