【问题标题】:Composing generic types in Java在 Java 中组合泛型类型
【发布时间】:2017-02-10 19:27:10
【问题描述】:

我在意想不到的情况下遇到类型不匹配错误。

public interface I {}

public abstract class C {}

public class A extends C implements I {}

public class B extends C implements I {}

public class Foo {

    public <T extends C & I> T getComposition(String selector) {
        switch (selector) {
            case "a": return new A(); // type-mismatch!
            case "b": return new B(); // type-mismatch!
        }
    }

}

为什么A(既是C又是I)不能以T返回?

【问题讨论】:

  • 如果我把你的方法称为foo.&lt;Hello&gt;getComposition(),这个方法应该返回一个Hello的实例,但它返回一个A的实例。 A 扩展了 C & I。T 也可以。但这并不意味着 T 和 A 是同一类。
  • 我错过了!谢谢@JBNizet。
  • @JBNizet 这个解释是有道理的,但是你能指出一些关于泛型这方面的进一步阅读吗?至少从我的角度来看,如果这是一个答案,我会赞成;-)
  • @GiovanniLovato,您可以将您的 new A() 转换为 T 并走得更远,但正如 JB Nizet 在下面某处所说,在您的代码中包含此类内容并不好。您能否提供更多详细信息,以便我们为您的真实案例提供帮助?
  • @GiovanniLovato 原因是 Test.class 属于 Class 类型。您不能将 Class 类型的引用分配给 Class 类型的变量,因为它们不是同一个东西。

标签: java generics types


【解决方案1】:

符号&lt;T extends C &amp; I&gt; 表示T 是一个类型参数。这意味着当有人调用该函数时,他们必须指定此类型。唯一的限制是类型扩展CIA 就是这样一种类型,但我可以创建一个新类,它还扩展了 CI。像这个例子:

class B extends C implements I {}

Foo foo = new Foo();
B b = foo.<B>getComposition();

如果您的示例已编译,这将导致异常,因为 AB 的类型不同。

如果你真的想只返回一个A,你需要删除泛型参数并直接返回类型A。像这样:

public class Foo {
    public A getComposition() {
        return new A();
    }
}

【讨论】:

  • 有没有办法用泛型来表达这样的“某事”,但里面有new A()
  • @GhostCat 我真的不明白为什么该方法首先是通用的。不应该,它的返回类型应该只是 A。我意识到实际情况可能更复杂,但我们对此一无所知。
  • @JBNizet 我已将示例更新为更类似于真实案例(当然这仍然只是一个示例)。
  • 如果我理解正确,您并不真的想让您的方法通用。您想要做的是返回一个实现 I 并扩展 C 的类型。您应该创建两个方法(一个返回 I,一个返回 C),或者创建一个抽象类 Foo 扩展 C 并实现 I 和 meke确保 A 和 B 都扩展了 Foo。
【解决方案2】:

你是对的,但只是一部分。 A 或 B 是 T,这是绝对正确的。但 T 本身根本不是 A 或 B。例如。我有另一个名为 D 和 D 扩展 A 的类。所以,D 也是 T。如果你说 T 是 A,你也意味着 D 是 A。这根本不正确,因为 D 是 A 的子类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多