java - 通用接口(interface)和通配符

标签 java generics wildcard

所以,我这里有这个小类层次结构:

public class Tst2 {
    /** interface allowing copying */
    private interface Copyable<T> {
        void copyFrom(T original);
    }

    /** Class which can be parameterized by types which can self-copy so it can copy those objects when it needs */
    private static class Manager<T extends Copyable<T>> {
        T value;

        Manager(final T value) {
            this.value = value;
        }

        void someWork() {
            value.copyFrom(value);
        }
    }

    /** and here's one example of the self-copying class for Manager to manipulate */
    private static class Box<T> implements Copyable<Box<T>> {
        T value;

        Box(final T value) {
            this.value = value;
        }

        T getValue() {
            return value;
        }

        void setValue(final T value) {
            this.value = value;
        }

        public void copyFrom(Box<T> original) {
            this.setValue(original.getValue());
        }
    }

    public static void main(String[] args) {
        Box<Object> objBox = new Box<Object>("object value");
        Manager<Box<Object>> objectManager = new Manager<>(objBox); // we have manager of Boxes with Objects
        objectManager.someWork();

        Box<String> strBox = new Box<String>("string value");
        Manager<Box<String>> stringManager = new Manager<>(strBox); // and here's manager of Boxes with Strings
        stringManager.someWork();   // all works well
    }
}

一切都很顺利。是的,您可能可以用不同的方式来编写它,但我喜欢这种特殊的编写方式 - 它简洁明了并且提供了我想要的一切。

所以我可以创建Manager<Box<String>>和其他每一个具体实现,完美。 所以现在让我们尝试通过声明变量来创建 ANY Box 的管理器:

Manager<Box<?>> anyManager;

以后想做类似下面的事情:

anyManager = (Manager<Box<?>>) (Manager<?>) new Manager<Box<Object>>(objBox);

糟糕,声明变量的问题(我还没有做任何转换):

Error:(52, 20) java: type argument Tst2.Box<?> is not within bounds of type-variable T

所以你不能创建任何Manager<Box<?>> !但可以肯定的是,ANY Box 实现了 Copyable,所以它应该适合那个

class Manager<T extends Copyable<T>>

对吧? 我猜它没有考虑到我的所有 Box 都实现了相同类型 Box 的可复制这一事实,所以它认为通配符可以来自不同的 box,或者类似的东西?

有人可以解释一下和/或建议解决方法吗? 再说一遍——我对有人重写整个解决方案不感兴趣,我只对修复这个特定的部分感兴趣。或者,至少,解释发生了什么。

最佳答案

这是 javac 或 ecj 中的错误,通常 ecj 在这些情况下是正确的。

但有人可能会争辩说:

Copyable> 不是 Box 的父类(super class)型(即使 ecj 也会告诉你)。但这就是当您将 T 替换为 Box 时绑定(bind)在 Manager 上的类型所需要的。

关于java - 通用接口(interface)和通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37856233/

相关文章:

java - 如何编写一个按钮,使其一开始呈灰色并禁用,直到填充 ImageView 为止?

c# - 使用泛型编写类似的逻辑

swift - 为什么 swift 不使用没有类型约束的通用返回参数来推断适当的重载函数?

java - 如何在 Kotlin 中传递有界通配符类型参数?

java - 按升序排列列表中的元素(首先是按递增方式排列的百分比,然后是不区分大小写的字母)

java - Cygwin CTRL-C(信号中断)无法正常工作 - JVM 关闭 Hook 未启动

java - 使用 Gson 解析带有嵌套数组的 json

list - 无法推断参数类型

javascript - jQuery 查找 TR->TH 值

linux - shell 脚本 - 当条件检查范围失败时