我现在有以下内容:
1) 一个Java接口。
2) 一个具体的Java类,但它没有实现上述接口,但包含了与接口中定义的每个方法匹配的方法签名。
由于我无法改变项目2的实现,我想知道是否可能使接受项目1实例作为参数的方法接受项目2而不会出现类转换异常。
感觉Spring中的各种编织/强制转换/AOP机制应该可以实现这一点,但我不知道如何做到。
有办法实现这个吗?
我现在有以下内容:
1) 一个Java接口。
2) 一个具体的Java类,但它没有实现上述接口,但包含了与接口中定义的每个方法匹配的方法签名。
由于我无法改变项目2的实现,我想知道是否可能使接受项目1实例作为参数的方法接受项目2而不会出现类转换异常。
感觉Spring中的各种编织/强制转换/AOP机制应该可以实现这一点,但我不知道如何做到。
有办法实现这个吗?
你无法让对象本身实现接口,但你可以使用类似Proxy的东西来创建一个实现接口并使用反射调用原始对象上适当成员的对象。
当然,如果只有一个接口类型和一个具体类型,你可以很容易地编写这样的包装器而不使用Proxy:
public class BarWrapper implements Foo
{
private final Bar bar;
public BarWrapper(Bar bar)
{
this.bar = bar;
}
public int someMethodInFoo()
{
return bar.someMethodInFoo();
}
// etc
}
这可以通过一个适配器来解决。 有另一个定义了实现你的接口并委托给真正对象的类:
class 你的适配器 implements 你的接口 {
private final 你的类 真正对象;
public 你的适配器(你的类 真正对象) {
this.真正对象 = 真正对象;
}
@Override
public 接口方法() {
// 你说这个类有相同的方法签名,尽管它没有实现接口,所以这应该可以正常工作:
真正对象.接口方法();
}
// .......
}
现在,给定一个期望 你的接口
的方法和一个类型为 你的类
的对象:
void 某个方法(你的接口 参数) {}
void 测试() {
你的类 对象 = 从某处获取();
某个方法( 你的适配器(对象) );
}
你可以使用Javassist来完成你想要的操作,可以通过修改类的字节码或创建一个包装/代理类来实现。
基本上有两种方法:
a) 在你的对象周围编写一个装饰器,实现接口并委托给你的对象(可以通过使用代理或编写一个简单的适配器类来实现)
b) 改变字节码。Spring AOP的功能不够强大,但是AspectJ编译器可以。只需要一行代码:
declare parents: YourClass implements YourInterface;
由于你无法访问类源代码,你需要使用加载时织入(Load Time Weaving)或织入库jar。所有这些都在 AspectJ in Action 一书中由 Ramnivas Laddad 很好地解释了。
是的,可以使用动态代理或字节码重写。然而,对我来说,你似乎在寻找适配器模式。