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

时间:2011-03-04 17:10:21

标签: java spring

现在我以下:

1)java接口。

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

由于我无法更改第2项的实现,因此我想知道是否可以创建一个接受第1项实例的方法作为参数接受第2项而不使用类转换异常。

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

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

5 个答案:

答案 0 :(得分:7)

  

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

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

答案 1 :(得分:3)

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

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

public class BarWrapper implements Foo
{
    private final Bar bar;

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

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

    // etc
}

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

基本上有两种方式:

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

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

declare parents: YourClass implements YourInterface;

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

答案 4 :(得分:0)

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

相关问题