Anh*_*ran 4 java generics java-8
我正在准备OCP证书,并且遇到了下界通配符的想法。如果我正确理解的话,当我们想让Java知道“绑定类型”总是可以添加到我们的通用Collection中时,将使用下界通配符。
例如:
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]
}
Run Code Online (Sandbox Code Playgroud)
由于“?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
}
Run Code Online (Sandbox Code Playgroud)
现在我们有了一个Predicate,它将接受1个参数,它是一个String或其超类,但是我们不确定它实际上是否是一个String(如果它只是一个对象呢?)。但是,我们仍然可以访问startsWith()
类似方法s
实际上是一个字符串。
为什么会这样?请给我解释一下。
Predicate<? super String> pred
可以分配为Predicate<String>
或Predicate<Object>
。您正在为其分配一个Predicate<String>
,这是允许的。由于您在lambda表达式中使用方法,因此编译器推断s -> s.startsWith("M")
为a 。Predicate<String>
String
例如,以下代码还将通过编译:
Predicate<? super String> pred = (Object o) -> o.hashCode() > 0;
Run Code Online (Sandbox Code Playgroud)
您还可以看到以下通过编译:
Predicate<String> preds = s -> s.startsWith("M");
Predicate<Object> predo = (Object o) -> o.hashCode() > 0;
Predicate<? super String> pred = preds;
pred = predo;
Run Code Online (Sandbox Code Playgroud)
即Predicate<? super String>
可以同时分配a Predicate<String>
和a Predicate<Object>
。
也就是说,请注意,pred.test()
它将仅接受String
,而不接受Object
。原因是该pred
变量可以引用a Predicate<Object>
或Predicate<String>
在运行时引用,并且String
两者都只能接受a 。
归档时间: |
|
查看次数: |
76 次 |
最近记录: |