繁体   English   中英

Java generics 下限

[英]Java generics lower bound

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

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的超级 class ,但编译期间没有错误。 因为我认为提供不相关的类型是非法的(我知道在类型推断之后不可能将非子 class 分配给t )。 它还可以与 collections 一起使用,这是否意味着集合可能不存储任何孩子,没有Base的超级 class ? 请不要将我链接到 PECS 问题,我已经阅读了很多。

我将添加此作为实际答案。

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

<? 之间的区别 超级 T> 和 <? 在 Java 中扩展 T>

请注意接受的答案给出的示例,尤其是带有<Object>的示例:

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());

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


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

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

如果您将声明更改为GenericsSuper<? super Base> main = new GenericsSuper<StringBuilder>(new StringBuilder()) GenericsSuper<? super Base> main = new GenericsSuper<StringBuilder>(new StringBuilder())你会得到你预期的错误。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM