【问题标题】:Java multiple interfaces and reflectionJava 多接口和反射
【发布时间】:2016-04-16 05:52:14
【问题描述】:

我有一个名为 X 的类,它实现了多个(例如 3 个)接口,分别称为 A、B 和 C。

我创建了另一个接口 AB 来扩展接口 A 和 B。

如何使用反射来创建可分配给接口 AB 的 X 实例?

我不断收到使用此代码的 ClassCast 异常:

package test.messages;

public interface A
{
    void methodA();
}

package test.messages;

public interface B
{
    void methodB();
}

package test.messages;

public interface C
{
    void methodC();
}

package test.messages;

public interface AB extends A, B
{

}

package test.messages;

public class X implements A, B, C
{
    @Override
    public void methodC()
    {
        System.out.println("C");
    }

    @Override
    public void methodB()
    {
        System.out.println("B");
    }

    @Override
    public void methodA()
    {
        System.out.println("A");
    }
}

然后在一个完全不同的类:

AB api = (AB)Class.forName("test.messages.X").newInstance();

System.out.println(api);

现在,当我尝试只使用一个接口时,比如 A,它可以正常工作。

有没有办法让它与组合接口 AB 一起工作?

【问题讨论】:

标签: java reflection interface


【解决方案1】:

is-a 关系不是这样工作的。 AB 实现 A 和 B 和 X 实现 A 和 B 的事实不会使 X 可分配给 AB。

即使您认为AB 与实现A 和B 的任何类型兼容,但情况并非如此,因为AB 是不同的类型,Java 中的层次结构树通过以下定义固定类本身。

想想Liskov substitution principle:如果你向AB 添加一个方法,那么X 不再是一个有效的候选对象,因为它不会包含AB 中声明的方法。

您需要一种支持structural type system 的编程语言才能做到这一点。

【讨论】:

  • 当您提到如果向接口 AB 添加方法会发生什么时,您很好地解释了为什么我的方法不起作用。但是,bayou.io 更好地理解了我想要做什么以及如何到达那里。
【解决方案2】:

您真正想要的是 AND 类型 -- A&B。这在 Java 中通常不受支持。但是,我们可以创建一个包含 A 类型和 B 类型的值的包装类。(似乎每个问题都可以通过包装解决:)

public class AB<T extends A&B>
{
    public final T v;

    ... 
        v = (T)Class.forName("test.messages.X").newInstance();
}

我们不使用类型A&amp;B,而是在需要的任何地方使用AB&lt;?&gt;。我们将在其字段v 上进行操作,即A 和B。

void foo(AB<?> ab)
{
    ab.v.methodOfA();
    ab.v.methodOfB();
}

或者您也可以将 AB 设为 A 和 B 的子类型。

public class AB<T extends A&B> implements A, B
{
    public final T v;

    @Override // A
    public int methodOfA(){ return v.methodOfA(); }

在https://stackoverflow.com/a/32659085/2158288查看更多信息

【讨论】:

    【解决方案3】:

    您不能这样做,因为在继承树中 X 没有实现 AB。 如果 A,B,C 都是接口,解决问题的简单方法是说 X 实现了 AB,C,这意味着它可以转换为 A、B、C 和 AB。

    【讨论】:

    • 虽然这适用于我正在处理的涉及 10 个接口的现实生活场景。因此,如果我要为这 10 个可能的组合创建一个单独的接口,我将拥有 1061 个额外的接口:)
    • 这很不方便,至少可以这么说。答案很有趣,尽管我必须承认我并不完全理解它是如何帮助的。难道你还不需要创建一大堆接口组合包装器吗?
    • 我是服务提供者,为每个服务功能公开一个接口。我正在为可能希望一次使用多个服务的服务消费者创建一个用户文档。我只想为消费者展示如何在一个类中组合多个接口。所以我不会创建组合,但消费者可能会......
    • 好的,现在说得通了 :) @BigMac66 感谢您的解释。
    猜你喜欢
    • 1970-01-01
    • 2016-06-16
    • 2011-10-18
    • 2012-05-06
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多