繁体   English   中英

Java 8下限有界通配符

[英]Java 8 lower bounded wildcard

我正在准备OCP证书,我想到了一个较低的有界通配符的想法。 如果我理解正确的话,当我们想让Java知道“有界类型”总是可以添加到我们的通用集合时,使用下限有界通配符。

例如:

public static void addInteger(List<? super Integer> list, Integer i)
{
    list.add(i);
}


public static void main(String[] args)
{   
    List<Number> list = new ArrayList<>();
    addInteger(list, 100);
    addInteger(list, 200);
    System.out.println(list);       // [100,200]

}

由于“?super Integer”表示类型必须是Integer或其超类,因此在列表中添加Integer将适用于每种情况。

但是,此代码仍然编译并运行正常:

public static void main(String[] args)
{   
    Predicate<? super String> pred = s -> s.startsWith("M"); // still compiles
    System.out.println(pred.test("Mon")); // Output true

}

现在我们有一个谓词,它将采用1个参数,这是一个String或它的超类,但我们不确定它实际上是一个字符串与否(如果它只是一个对象怎么办?)。 但是,我们仍然可以访问startsWith()方法,就像s实际上是一个String。

为什么会这样? 请向我解释。

Predicate<? super String> pred Predicate<? super String> pred可以分配Predicate<String>Predicate<Object> 您正在为其分配一个允许的Predicate<String> 编译器推断s -> s.startsWith("M")是一个Predicate<String>因为你在lambda表达式中使用了String方法。

例如,以下内容也将通过编译:

Predicate<? super String> pred = (Object o) -> o.hashCode() > 0;

您还可以看到以下传递编译:

Predicate<String> preds = s -> s.startsWith("M");
Predicate<Object> predo = (Object o) -> o.hashCode() > 0;
Predicate<? super String> pred = preds;
pred = predo;

Predicate<? super String> Predicate<? super String>既可以分配Predicate<String> ,也可以分配Predicate<Object>

也就是说,注意pred.test()只接受String ,而不接受任何Object 原因是pred变量可以在运行时引用Predicate<Object>Predicate<String> ,并且两者都只接受String

你似乎对Predicate对象实例的类型(由lambda创建)和pred类型(对该对象的引用)之间的区别感到困惑。

  • 由lambda创建的Predicate实例的类型为Predicate<String>

  • 参考pred的对象的类型是Predicate<? super String> Predicate<? super String> ,因此可以分配Predicate<Object>Predicate<String>类型的值。 但是谓词的test方法只能用String对象调用!

    那是什么? super String ? super String绑定确保。

对象实例总是具有某些具体类型的类型参数,如ObjectString 只有引用可以具有通配符类型的类型参数。

暂无
暂无

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

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