簡體   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