public interface Person {
void eat();
}
public class Student implements Person {
@Override
public void eat() {
System.out.println("吃饭");
}
}
public class PersonProxy implements InvocationHandler{
private Person p;
public PersonProxy(Person obj){
this.p=obj;
}
@Override
public Person invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("eat")){
System.out.println("代理测试");
}
return (Person) method.invoke(p, args);
}
public Object getProxy(){
return Proxy.newProxyInstance(p.getClass().getClassLoader(), p.getClass().getInterfaces(), this);
}
}
public class Mytest {
public static void main(String[] args) {
Person p=(Person) new PersonProxy(new Student()).getProxy();
p.eat();
//这里会报类型转换错误
Student st=(Student) new PersonProxy(new Student()).getProxy();
st.eat();
}
}
想知道为啥我传的是Student对象,为哈转Student调用eat()方法会报类型转换异常?转Person就不会有异常!
虽然Proxy传入的是Student对象,但是getProxy方法返回的不是这个Student对象,而是代理动态生成的一个类(比如Proxy$0)的实例。
这个新生成的类Proxy$0实现了Person接口,跟Student类不是一个,是实现了同一个接口的两个类。因此:
getProxy方法得到的实例转成Person没有问题,因为它的类确实实现了Person接口,但是转成Student报错,因为它们是两个类。
动态代理的详细原理已有问题解答可以参考:http://ask.csdn.net/questions/233571
在你的代理类中的invoke方法中 返回的是return (Person) method.invoke(p, args); Person对象,也就是说你通过代理获得是Person对象,
根据java的继承,父类转子类肯定会报错
希望能帮到你