csdn上的反射和代理的好例子

[code]/**
*这个程序的功能是通过反射技术得到一个类(SrcClass)的两个String类型的成员变量
*然后经过判断对字符串进行处理
*这个题目的特点:通过对API的阅读了解Class类的使用方法
*1、getDeclaredFields()得到所有的成员变量
*2、Field类中的一些方法getType()
*3、Field类继承于AccessibleObject类,有一个setAccessible()方法,查看API得到他的用途
**/
import java.lang.reflect.Field;
class SrcClass
{
private String name = "BeiJing.2008";//定义来两个String类型的变量,访问修饰都是私有的
private String eMail = "BeiJing.2008@163.com";
private int age = 25;


public String toString()//覆盖父类的toString方法,打印数据
{
return "Name:[ " + this.name + " ] EMail: [ " + this.eMail + " ] Age: [ " + this.age + " ]";
}
}

public class TestClass
{


public static void main(String[] args)
{
SrcClass srcclass = new SrcClass();//首先实例化一个SrcClass类的实例,用于给amendString方法传值
TestClass testclass = new TestClass();//再实力化一个TestClass的实例

System.out.println(srcclass);//打印一遍原始信息


testclass.amendString(srcclass);//调用amendString方法
System.out.println(srcclass);//打印一遍修改后的信息

}


public void amendString(Object cls)//用于修改通过代理得到srcclass的String成员变量,进行替换处理
{
try
{
Field[] fidles = cls.getClass().getDeclaredFields();//得到srcclass.getClass()类中的所有成员变量
for(Field field : fidles)//增强for循环
{
if(field.getType().equals(java.lang.String.class))//判断这个成员变量的类型是不是String类型的
{ //如果返回true就进行处理
field.setAccessible(true);//设置这个变量不进行访问权限检查(我在SrcClass里设置的变量为private)
String newString = (String)field.get(cls);//通过Field类的get方法得到String成员变量

field.set(cls,newString.replaceAll("BeiJing","China"));//进行替换,再调用Field类的set方法进行修改
}
}
}

catch(SecurityException e)//
{
e.printStackTrace();
}

catch (IllegalArgumentException e)
{

e.printStackTrace();
}

catch (IllegalAccessException e)
{

e.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
}

}

------------------------------------------------

下面就是代理了,实现代理必须有4个类(一个接口3各类)

public interface FooInterface {
public String printMassage();
}

---------------------------------------------

class ImplementFoo implements FooInterface {

public String printMassage()
{
return "This is ImplementFoo ...";
}
}



---------------------------------------------

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

class ImplementInvocationHandler implements InvocationHandler
{
private Object foo;

public ImplementInvocationHandler(Object foo) //获得将要运行类的实际对象
{
this.foo = foo;
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable //
{
System.out.println("You want use " + proxy.getClass().getName() + "." +

method.getName() + " at " + new Date());
return method.invoke(foo);//方法调用
}

}

---------------------------------------------

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
/**
* InvocationHandler handler = new MyInvocationHandler(...);
Class proxyClass = Proxy.getProxyClass(
Foo.class.getClassLoader(), new Class[] { Foo.class });
Foo f = (Foo) proxyClass.
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });

*
*/
public class TestProxy {


public static void main(String[] args)
{
ImplementFoo foo = new ImplementFoo();//实例化一个实现了FooInterface(自己定义的)接口的类
InvocationHandler handler = new ImplementInvocationHandler(foo);
//自己编写实现InvocationHandler接口的类
//并且将他实例化,ImplementInvocationHandler类中有一个构造函数需要接受一个ImplementFoo类的对象, 因为我们将来
//要使用ImplementFoo.printMassage方法,ImplementInvocationHandler类方法invoke中的method.invoke(foo)
//需要知道他将调用谁的printMassage方法,所以我们要给ImplementInvocationHandler类传递一个ImplementFoo类的对象

Class proxyClass = Proxy.getProxyClass(FooInterface.class.getClassLoader(),FooInterface.class);
//此时我们就要制造出一个代理类了,使用Proxy类的静态方法getProxyClass,查看API得到答案

FooInterface f;
try
{

f = (FooInterface) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).newInstance(handler);
System.out.println(f.hashCode());//动态实例化出一个代理类,并且调用他的hashCode、printMassage方法
System.out.println(f.printMassage());

} catch (SecurityException ex) {
ex.printStackTrace();
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
} catch (NoSuchMethodException ex) {
ex.printStackTrace();
} catch (InvocationTargetException ex) {
ex.printStackTrace();
}

}

}[/code]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值