Java - IsAssignableFrom 悖论?

标签 java

我有一些第三方类(class)。其精简版(为了简洁起见)功能如下:

  • 提供两个类 ClassAClassB 供外部使用。这些类中的每一个类都与其他类完全无关(这意味着它们没有共同的祖先)。
  • 有一个handle()函数,它接受Object类型的对象作为输入。
  • handle() 函数检查对象的类型是否为 ClassAClassB
  • 如果类型匹配,代码将调用具有相同对象参数的用户定义函数。

该类的伪代码及其用法如下:

// Third party code..

class ClassA implements InterfaceA { ... }
class ClassB { ... }

class WeirdCode {
    void registerUserMethod(func ...) { }
    void handle(Object input) { ... }
}


// My caller code..

function myHandler(T??? obj) {
    // Do something with obj
}

WeirdCode weirdCode = new WeirdCode(...);
weirdCode.registerUserMethod(myHandler);

weirdCode.handle(new ClassA(...));

通常,该类应一次专门用于一种类型。因此,我可以使用 ClassAClassB,但不能同时使用两者。但是,如果我想同时处理 ClassAClassB 对象,我必须这样做:

// My caller code..

function myHandlerA(ClassA obj) { ... }
function myHandlerB(ClassB obj) { ... }

WeirdCode weirdCodeA = new WeirdCode(...);
WeirdCode weirdCodeB = new WeirdCode(...);

weirdCodeA.register(myHandlerA);
weirdCodeB.register(myHandlerB);

weirdCodeA.handle(new ClassA(...));
weirdCodeB.handle(new ClassB(...));

我希望能够执行以下操作:

// My caller code..

function myHandlerAB(Object obj) { ... }

WeirdCode weirdCode = new WeirdCode(...);

weirdCode.handle(new ClassA(...));
weirdCode.handle(new ClassB(...));

但是,如果我这样做,WeirdCode 会抛出异常,因为其中包含以下代码:

void handle(Object obj) {
    ...
    if (ClassA.class.isAssignableFrom(obj.getType())) {
        ...
        myHandler(obj);
    }
    else if (ClassB.class.isAssignableFrom(obj.getType())) {
        ...
        myHandler(obj);
    }
    else {
        throw new Exception();
    }
    ...
}

在整个图中我唯一可以控制的是myHandler()函数的原型(prototype)。是否可以定义一个类型,使得 ClassAClassB 都可以从中分配,以及 ClassAClassB 可以转换到它吗?我认为这是不可能的。但我很乐意被证明是错误的,因为这会帮助我解决我的问题。

最佳答案

The only thing I can control in this entire picture is the prototype of the myHandler() function. Is it possible to define a type such that both ClassA and ClassB are assignable from it, as well as both ClassA and ClassB to be cast-able to it?

所以你想做的是:

MyType myType1 = new ClassA(...);
MyType myType2 = new ClassB(...);

还有...

ClassA clsA = (ClassA) myType1;
ClassB clsB = (ClassB) myType2;

准确吗?

你的致命弱点是你无法控制 ClassA 和 ClassB 的类型。据我了解,这些对象是由第三方代码定义的,您无法修改。听起来您想要做的是提供一种有限多重继承的形式,这可以通过接口(interface)继承来提供。但是,由于您无法控制这些类,因此该解决方案不可行。

尽管 instanceof 运算符经常被 mock 为良好的面向对象软件设计的祸根,但在这种必须与其他人的代码进行互操作的情况下,它是必不可少的。

FWIW,Java 并不以通常理解的方式理解“原型(prototype)”(例如 JavaScript 中的原型(prototype)继承)。您不应该试图强制 Java 理解原型(prototype)继承。

关于Java - IsAssignableFrom 悖论?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34124712/

相关文章:

java - 当java代码中的可见性更改为可见时,进度条不显示

java - spring boot jpa - 创建定义名称为 'entityManagerFactory' 的 bean 时出错

java - 使用递归比较字符串

java - Android:无法使用 null 启动服务:java.lang.NullPointerException

java - 如何在android动态键值对中动态获取JSON格式的输入数据

java - JVM按顺序启动线程的run()方法的保证是什么

java - tomee 不会从 eclipse 中启动

java - 使用java将图像大小MB减少到KB

java - Eclipse:主函数存在时出现 "selection does not contain a main type"错误

java - 从 JDL 文件添加 jHipster 实体时出错