繁体   English   中英

Java 动态代理 - class 实现多个接口

[英]Java dynamic proxies - class implements multiple interfaces

我正在查看一些 Java 动态代理示例。 一个简单的拦截方法调用并添加一些打印输出的基本方法:

public interface IVehicle {
    public void forward();
}

public class Car implements IVehicle {
    private String name;

    public Car(String name) {this.name = name;}

    public void forward() {
        System.out.println("Car " + name + " forward");
    }
}

public class VehicleHandler implements InvocationHandler {
    private Car v;
    public VehicleHandler(Car v) {this.v = v;}
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        System.out.println("Vehicle Handler: Invoking " + m.getName());
        return m.invoke(v, args);
    }
}

public class Client {
    public static void main(String[] args) {
        Car c = new Car("audi");
        ClassLoader cl = Car.class.getClassLoader();
        IVehicle v = (IVehicle) Proxy.newProxyInstance(cl,
            new Class[] {IVehicle.class}, new VehicleHandler(c));

        v.forward();
    }
}

此示例运行良好,并打印出处理程序和 object 消息。 但后来我在想,如果上面示例中的 Car class 实现了多个接口,我在所有实现的接口中调用所有方法怎么办?

我将上面的示例编辑为(更改由 ** 包围):

public interface IVehicle {
    public void forward();
}

**public interface IVehicle2 {
    public void forward2();
}**

public class Car implements IVehicle, **IVehicle2** {
    private String name;

    public Car(String name) {this.name = name;}

    public void forward() {
        System.out.println("Car " + name + " forward");
    }

    **public void forward2() {
        System.out.println("Car " + name + " forward2");
    }**
}

public class VehicleHandler implements InvocationHandler {
    private Car v;
    public VehicleHandler(Car v) {this.v = v;}
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        System.out.println("Vehicle Handler: Invoking " + m.getName());
        return m.invoke(v, args);
    }
}

public class Client {
    public static void main(String[] args) {
        Car c = new Car("audi");
        ClassLoader cl = Car.class.getClassLoader();
        **Car** v = **(Car)** Proxy.newProxyInstance(cl,
            new Class[] {IVehicle.class, **IVehicle2.class**}, new VehicleHandler(c));

        v.forward();
        **v.forward2();**
    }
}

我收到以下错误:

Exception in thread "main" java.lang.ClassCastException: class com.sun.proxy.$Proxy0 cannot be cast to class Car

我的问题是: 1. 为什么会出现上述错误? 2. 如果我想在上面的例子中同时调用forward()forward2() ,我该如何正确地做代理?

非常感谢!

您正在实现代理 class, ie Car 动态代理的想法是在运行时生成“代理类”,即不需要在编译时实现代理 class。

在此代码段中

**Car** v = **(Car)** Proxy.newProxyInstance(cl,
        new Class[] {IVehicle.class, **IVehicle2.class**}, new VehicleHandler(c));

将代理实例分配给它实现的接口之一。 根据分配给它的接口,可以在代理上调用相应的方法。

如果您想要一个可以调用任一接口方法的single proxy ,则拥有一个扩展IVehicleIVehicle2的通用接口; 然后使用公用接口作为代理class,即(通过Proxy.newProxyInstance将代理rcvd.赋值给公用接口。

注意: Car class 可用于其他用途,包括装载机 class。 将其用作代理 class 时, ie**Car** v = **(Car)** Proxy.newProxyInstance它不是动态代理 class。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM