[英]Java 8 lower bounded wildcard
I'm preparing for OCP certificate, and I came across with the idea of a lower bounded wildcard. 我正在准备OCP证书,我想到了一个较低的有界通配符的想法。 If I understand it correctly, the lower bounded wildcard is used when we want to let Java know the "bounded type" can always be added to our generic Collection. 如果我理解正确的话,当我们想让Java知道“有界类型”总是可以添加到我们的通用集合时,使用下限有界通配符。
For example: 例如:
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]
}
Since "? super Integer" indicates that the type must be an Integer or its superclass, adding an Integer to the list will work in each case. 由于“?super Integer”表示类型必须是Integer或其超类,因此在列表中添加Integer将适用于每种情况。
However, this code still compiles and runs like normal: 但是,此代码仍然编译并运行正常:
public static void main(String[] args)
{
Predicate<? super String> pred = s -> s.startsWith("M"); // still compiles
System.out.println(pred.test("Mon")); // Output true
}
Now we have a Predicate that will take 1 parameter which is a String or its super class, but we're not sure it's actually a String or not (What if it's just an Object?). 现在我们有一个谓词,它将采用1个参数,这是一个String或它的超类,但我们不确定它实际上是一个字符串与否(如果它只是一个对象怎么办?)。 However, we can still access startsWith()
method like s
is actually a String. 但是,我们仍然可以访问startsWith()
方法,就像s
实际上是一个String。
Why does this happen? 为什么会这样? Please explain to me. 请向我解释。
Predicate<? super String> pred
Predicate<? super String> pred
can be assigned either a Predicate<String>
or a Predicate<Object>
. Predicate<? super String> pred
可以分配Predicate<String>
或Predicate<Object>
。 You are assigning to it a Predicate<String>
, which is allowed. 您正在为其分配一个允许的Predicate<String>
。 The compiler infers that s -> s.startsWith("M")
is a Predicate<String>
since you are using a String
method in the lambda expression. 编译器推断s -> s.startsWith("M")
是一个Predicate<String>
因为你在lambda表达式中使用了String
方法。
For example, the following will also pass compilation: 例如,以下内容也将通过编译:
Predicate<? super String> pred = (Object o) -> o.hashCode() > 0;
You can also see that the following passes compilation: 您还可以看到以下传递编译:
Predicate<String> preds = s -> s.startsWith("M");
Predicate<Object> predo = (Object o) -> o.hashCode() > 0;
Predicate<? super String> pred = preds;
pred = predo;
ie Predicate<? super String>
即Predicate<? super String>
Predicate<? super String>
can be assigned both a Predicate<String>
and a Predicate<Object>
. Predicate<? super String>
既可以分配Predicate<String>
,也可以分配Predicate<Object>
。
That said, note that pred.test()
will only accept String
s, and not any Object
. 也就是说,注意pred.test()
只接受String
,而不接受任何Object
。 The reason is that the pred
variable can reference either a Predicate<Object>
or Predicate<String>
at runtime, and only a String
is acceptable by both. 原因是pred
变量可以在运行时引用Predicate<Object>
或Predicate<String>
,并且两者都只接受String
。
Your seem to be confused about the difference between the type of the Predicate
object instance (that is created by the lambda) and type of pred
, the reference to that object. 你似乎对Predicate
对象实例的类型(由lambda创建)和pred
类型(对该对象的引用)之间的区别感到困惑。
The Predicate
instance that is created by the lambda has type Predicate<String>
. 由lambda创建的Predicate
实例的类型为Predicate<String>
。
The reference pred
to the object is of type Predicate<? super String>
参考pred
的对象的类型是Predicate<? super String>
Predicate<? super String>
, and can thus be assigned values of both type Predicate<Object>
and Predicate<String>
. Predicate<? super String>
,因此可以分配Predicate<Object>
和Predicate<String>
类型的值。 But the test
method of the predicate can only be called with String
objects! 但是谓词的test
方法只能用String
对象调用!
That's what the ? super String
那是什么? super String
? super String
bound ensures. ? super String
绑定确保。
Object instances always have type parameters of some concrete type, like Object
or String
. 对象实例总是具有某些具体类型的类型参数,如Object
或String
。 Only references to can have type parameters of wildcard types. 只有引用可以具有通配符类型的类型参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.