简体   繁体   English

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

[英]Java dynamic proxies - class implements multiple interfaces

I'm looking at some Java dynamic proxies examples.我正在查看一些 Java 动态代理示例。 A basic one which simply intercepts a method call and add some print-out:一个简单的拦截方法调用并添加一些打印输出的基本方法:

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();
    }
}

This example works well and prints out handler and object messages.此示例运行良好,并打印出处理程序和 object 消息。 But then I'm thinking what if the Car class in above example implements multiple interfaces and I call all methods in all implemented interfaces?但后来我在想,如果上面示例中的 Car class 实现了多个接口,我在所有实现的接口中调用所有方法怎么办?

I edited above example to (Changes are surrounded by **):我将上面的示例编辑为(更改由 ** 包围):

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();**
    }
}

I got below error:我收到以下错误:

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

My questions are: 1. why do I get above error?我的问题是: 1. 为什么会出现上述错误? 2. How do I correctly do proxy if I want to call both forward() and forward2() in above example? 2. 如果我想在上面的例子中同时调用forward()forward2() ,我该如何正确地做代理?

Thanks a lot!非常感谢!

You're implementing the Proxy class, ie Car at compile time.您正在实现代理 class, ie Car The idea of dynamic proxy is to have the 'proxy class' generated at runtime, ie the proxy class implementation at compile time is not needed.动态代理的想法是在运行时生成“代理类”,即不需要在编译时实现代理 class。

In this code snippet在此代码段中

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

Have the proxy instance assigned to one of interface that it implements.将代理实例分配给它实现的接口之一。 Based on the interface it's assigned to, the corresponding method can be invoked on the proxy.根据分配给它的接口,可以在代理上调用相应的方法。

If you want a single proxy that can invoke either of the interface's method, then have a common interface that extends both IVehicle and IVehicle2 ;如果您想要一个可以调用任一接口方法的single proxy ,则拥有一个扩展IVehicleIVehicle2的通用接口; and then use the common interface as the proxy class, ie (assign proxy rcvd. through Proxy.newProxyInstance to the common interface.然后使用公用接口作为代理class,即(通过Proxy.newProxyInstance将代理rcvd.赋值给公用接口。

Note: the Car class can be used for other purposes it may have, including it being the loader class.注意: Car class 可用于其他用途,包括装载机 class。 When using it as the proxy class, ie**Car** v = **(Car)** Proxy.newProxyInstance it's not a dynamic proxy class.将其用作代理 class 时, ie**Car** v = **(Car)** Proxy.newProxyInstance它不是动态代理 class。

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

相关问题 实现多个接口的类的类型 - Type of class which implements multiple interfaces Mockk - 模拟实现多个接口的最终类​​时出现 ClassCastException - Mockk - ClassCastException when mocking final class that implements multiple interfaces 如何在 JRuby 中指定 Ruby class 实现几个 java 接口 - How to specify in JRuby that a Ruby class implements several java interfaces 如果一个类实现了多个接口,应该将equals()实现到哪个接口? - If a class implements multiple interfaces, to which interface should `equals()` be implemented to? 关于Java方法和实现多个接口的参数 - About Java method & a parameter which implements multiple interfaces java动态代理与常规代理的有用性 - Usefulness of java dynamic proxies vs regular proxies 在扩展类上,我可以使用实现多个接口的类的getter和setter方法吗 - On a extended class, can i use a getter and setter of a class that implements multiple interfaces 如果 class 使用类似方法实现多个接口,它是否会过载? - Is it overloading if a class implements muplitple interfaces with similar methods? 实例化类的替代方法不实现父接口 - Alternative way to instantiate a class not implements the parent interfaces 一个类的好习惯是实现两个或多个接口吗? - Is a good practice to a class implements two or more interfaces?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM