您可以强制java对象在运行时实现接口吗?

您可以强制java对象在运行时实现接口吗?,java,spring,Java,Spring,我现在要说的是: 1) java接口 2) 一个具体的java类,它不实现上述接口,但包含一个方法签名,该签名与接口中定义的每个方法都匹配 由于我无法更改项2的实现,我想知道是否有可能使一个接受项1的实例作为参数的方法在没有类强制转换异常的情况下接受项2 感觉春天的各种编织/强制/AOP机制应该使这成为可能,但我不知道如何做到这一点 有没有办法做到这一点 您可以强制java对象在运行时实现接口吗 是,使用或字节码重写。然而,在我看来,您似乎在寻找。您不能让对象本身实现接口,但您可以使用类似的方法

我现在要说的是:

1) java接口

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

由于我无法更改项2的实现,我想知道是否有可能使一个接受项1的实例作为参数的方法在没有类强制转换异常的情况下接受项2

感觉春天的各种编织/强制/AOP机制应该使这成为可能,但我不知道如何做到这一点

有没有办法做到这一点

您可以强制java对象在运行时实现接口吗


是,使用或字节码重写。然而,在我看来,您似乎在寻找。您不能让对象本身实现接口,但您可以使用类似的方法创建一个实现接口的对象,并使用反射来调用原始对象上的相应成员

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

public class BarWrapper implements Foo
{
    private final Bar bar;

    public BarWrapper(Bar bar)
    {
        this.bar = bar;
    }

    public int someMethodInFoo()
    {
        return bar.someMethodInFoo();
    }

    // etc
}

基本上有两种方式:

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

b) 更改字节码。SpringAOP的功能还不足以做到这一点,但AspectJ编译器是。这是一条单行线:

declare parents: YourClass implements YourInterface;

由于您没有访问类源的权限,因此必须使用加载时编织或编织库jar。所有这些都在中得到了很好的解释,这应该可以通过适配器解决。 定义一个实现接口并委托给真实对象的其他类:

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

您可能可以通过修改类的字节码或创建一个包装器/代理类来执行您想要的操作。

您不能只制作一个实现接口并转发所有内容的包装器吗?有人知道这个模式是否有名称(OP想要什么)您在何处将具有匹配签名的对象“强制”到接口上?您是否有关于如何执行此操作的任何文档的链接,最好是声明式的?@dskiles,使用代理,请参阅。对于AoP方法,请看一下or项目。适配器模式是一个不错的选择,但是一种语言需要一个对象来显式实现它将满足的所有接口,这有点疯狂。隐式接口无疑是一种方法,但这对Java程序员没有帮助。这就是我现在所做的,但我希望尽可能跳过适配器步骤。如果你不介意反射,那么你需要使用其他答案中提到的代理方法。