你能强制一个java对象在运行时实现一个接口吗?

现在我以下:

1)一个java接口。

2)一个具体的java类,它实现上述接口,但包含一个方法签名,该签名匹配接口中定义的每个方法。

由于我无法更改第2项的实现,因此我想知道是否可以创建一个方法来接受第1项的实例作为参数接受第2项而没有类强制转换exception。

感觉就像Spring中的各种编织/强制/ AOP机制应该使这成为可能,但我不知道该怎么做。

有没有办法让这种情况发生?

你能强制一个java对象在运行时实现一个接口吗?

是的,使用动态代理或字节码重写。 但是,对我而言,您似乎正在寻找Adapter pattern

您无法使对象本身实现接口,但您可以使用Proxy之类的东西来创建实现接口的对象,并使用reflection来调用原始对象上的相应成员。

当然,如果它只是一种接口类型和一种具体类型,您可以轻松编写这样的包装器而不使用代理:

 public class BarWrapper implements Foo { private final Bar bar; public BarWrapper(Bar bar) { this.bar = bar; } public int someMethodInFoo() { return bar.someMethodInFoo(); } // etc } 

这应该可以通过适配器解决。 定义了另一个实现接口并委托给真实对象的类:

 class YourAdapter implements YourInterface { private final YourClass realObject; public YourAdapter(YourClass realObject) { this.realObject = realObject; } @Override public methodFromInterface() { // you said the class has the same method signatures although it doesn't // implement the interface, so this should work fine: realObject.methodFromInterface(); } // ....... } 

现在,给定一个期望YourInterface的方法和一个类型为YourClass的对象:

 void someMethod(YourInterface param) {} void test() { YourClass object = getFromSomewhere(); someMethod( YourAdapter(object) ); } 

您可以通过修改类的字节码或创建包装器/代理类来完成Javassist所需的操作。

基本上有两种方法:

a)在你的Object周围编写一个装饰器来实现接口并委托给你的对象(这可以通过使用代理或编写一个简单的适配器类来完成)

b)更改字节代码。 Spring AOP不够强大,但是AspectJ编译器是。 这是一个单行:

 declare parents: YourClass implements YourInterface; 

由于您无权访问类源,因此您必须使用“加载时间编织”或编织库jar。 所有这些都在 Ramnivas Laddad的 AspectJ in Action中得到了很好的解释