【问题标题】:Java generics lower boundJava 泛型下界
【发布时间】:2021-11-29 04:11:25
【问题描述】:

我清楚地了解上限,但不完全了解下限。例如我有这个代码:

public class Main<T> {
    private T t;

    public Main(T t) {
        this.t = t;
    }

    private static class Base {}

    public static void main(String[] args) {
        Main<? super Base> main = new Main<>(new StringBuilder());
        System.out.println(main.t.getClass());
    }
}

尽管StringBuilder 不是Base 的超类,但为什么编译期间没有错误。因为我认为提供不相关的类型是非法的(我知道在类型推断之后不可能将非子类分配给t)。它也适用于集合,这是否意味着集合可能不存储子级,不存储Base 的超类?请不要将我链接到 PECS 问题,我已经阅读了很多。

【问题讨论】:

  • 你必须把你的 Main 类写成 public class Main
  • 我认为&lt;T&gt; 这里是Object,它是Base 和String 的合法超类型。基本上,您这样做/考虑这一点的方式是有缺陷的。查看此问题的答案(忽略 PECS 的重复文本):stackoverflow.com/questions/4343202/…

标签: java generics


【解决方案1】:

编辑:我看到它有点晚了,@markspace 的答案 几乎相同,并在此之前发布。由于解释方式不同,我在这里只保留这一点,仅此而已。


这应该是由于菱形运算符&lt;&gt; 自动推断基于最可能的路线发生的,在这种情况下是构造函数参数。

我找不到菱形运算符的官方描述,但各种来源对其大意进行了描述 - 当给定菱形运算符特性确定最合适的构造函数声明时,Java 编译器会进行类型推断匹配调用。

如果您将声明更改为GenericsSuper&lt;? super Base&gt; main = new GenericsSuper&lt;StringBuilder&gt;(new StringBuilder()),您将收到预期的错误。

如果没有这个显式声明,&lt;&gt; 会由于 super 限制而导致 &lt;Object&gt;,因此任何事情都是允许的,因为:

  • GenericsSuper 中的代码与StringBuilder 没有问题。它只想要T。
  • Base 与StringBuilder 在Object 中有一个共同的超级。

【讨论】:

    【解决方案2】:

    我将添加这个作为实际答案。

    我认为&lt;T&gt; 这里是Object,它是Base 和StringBuilder 的合法超类型。基本上,您这样做/考虑这一点的方式是有缺陷的。查看此问题的答案(忽略 PECS 的重复文本):

    Difference between <? super T> and <? extends T> in Java

    注意接受的答案给出的例子,尤其是带有&lt;Object&gt;的例子:

    List<? super Integer> foo3 = new ArrayList<Integer>();  // Integer is a "superclass" of Integer (in this context)
    List<? super Integer> foo3 = new ArrayList<Number>();   // Number is a superclass of Integer
    List<? super Integer> foo3 = new ArrayList<Object>();   // Object is a superclass of Integer
    

    由于您允许菱形运算符“找出”T 的类型,它“找出”Object 工作并使用它。未经测试,但检查这是否也编译:

    Main<? super Base> main = new Main<Object>(new StringBuilder());
    

    【讨论】:

    • 尽管如此,但我不知道如何在运行时检查实际的泛型类型,尽管泛型是擦除类型,但有一些方法可以在运行时获取实际类型,但它们没有帮助。
    猜你喜欢
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多