在你的問題中,你不清楚什麼是擴展,你需要爲此使用反射。因爲你可以通過反射創建你的實例,然後簡單地將它包裝到代理或裝飾器中,以增強或改變它的行爲。
class MyFactory {
MyClass create() {
return MyDecorator(cls.newInstance());
}
}
凡MyDecorator
實現了一樣的公共接口,當然MyClass
。
但是,如果您真的需要通過反射來做到這一點,我知道有幾種可能的方法可能會起作用,具體取決於您的想法。
使用Java代理
如果您在問題的方法來自於一個界面,你可以使用Java Proxy改變其行爲。
OrderService subject = new DefaultOrderService();
OrderService orderService = (OrderService) Proxy.newProxyInstance(
this.getClass().getClassLoader(),
new Class<?>[]{OrderService.class},
(proxy, method, args) -> {
try {
System.out.println("Before method");
return method.invoke(subject, args);
}
finally {
System.out.println("After method");
}
}
);
System.out.println(orderService.getClass());
orderService.getOrder(10);
上述收益率有點像這樣的類名的輸出:com.sun.proxy.$Proxy24.class
爲類代理的。
使用Java CGLIB
但是,如果你被迫使用普通類,而不是一個接口,那麼你可以使用庫像cglib代替。
代理包含從原始類繼承(即DefaultOrderService)。這有一個好處;它不需要所討論的類實現一個接口,以便能夠創建代理,這在你的問題中似乎就是這種情況。
DefaultOrderService subject = new DefaultOrderService();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(DefaultOrderService.class);
enhancer.setCallback((InvocationHandler) (obj, method, args) -> {
try {
System.out.println("Before method");
return method.invoke(subject, args);
}
finally {
System.out.println("After method");
}
});
OrderService orderService = (OrderService) enhancer.create();
System.out.println(orderService.getClass());
orderService.getOrder(10);
上面的輸出產生的結果有點像DefaultOrderService$$EnhancerByCGLIB$$9017bdba.class
作爲增強對象的類。
但是,這兩個示例都是關於定義一個與另一個接口具有相同接口的新類,它們不會更改原始父類或接口。
你最後的例子正是我需要的謝謝你!不幸的是,它不適用於Android(我的項目基於此),因爲CGlib生成Java字節碼,而Android則運行Dalvik字節碼。您是否知道Android的替代方案提供了相同的功能?編輯:我實際上只是發現http:// bytebuddy。網絡/並將看看它作爲聲稱支持Android的最新版本 – Phoebus