Java 8 Optional.ifPresent 是我的代码错了还是eclipse?
Java 8 Optional.ifPresent is my code wrong or is it eclipse?
我是 Java 8 的新手,正在尝试 Null 类型注释和 Optional。
对于我下面的示例,我使用了 String 而不是我的 class 并且我调用 toUpperCase 只是为了调用一些东西,在我的例子中我实际上调用了一个传递参数的函数(所以不要认为我可以使用 :: operator and/or maps).
在 Eclipse 中,我打开了 Java - 编译器 - Errors/Warnings - 空分析错误。
我的测试代码如下:
public void test1(@Nullable String s) {
// the 2nd s2 has a Potential null pointer access error.
// I was hoping ifPresent would imply NonNull
Optional.ofNullable(s).ifPresent(s2 -> s2.toUpperCase());
}
@Nullable
public String getSomeString() {
return null;
}
public void test2() {
String s = getSomeString();
// This is fine, unlike the first example, I would have assumed that
// it would know s was still nullable and behave the same way.
Optional.ofNullable(s).ifPresent(s2 -> s2.toUpperCase());
}
似乎使用 Eclipse 类型空注释和 Optional.ifPresent 不能很好地结合在一起。
我是在浪费时间尝试让这样的东西工作吗?我是否应该恢复为将 getter 分配给临时变量然后检查是否为 null,如果不是则调用我的函数?
首先:@Nullable
接缝不属于 public Java 8 SDK。查看您导入的包:com.sun.istack.internal.Nullable
.
其次:我有 运行 你的两种方法:test1(null)
和 test2()
并且没有发生任何异常情况。一切都很好(正如预期的那样)。那么你观察到了什么?
运行 test1(null)
=> 没有执行 lambda 表达式。
运行 test2() => 没有执行 lambda 表达式。
我按照以下方式更改了您的测试代码:
public void test1(@Nullable String s) {
Optional.ofNullable(s).ifPresent(s2 -> System.out.println("executed"));
}
public void test2() {
String s = getSomeString();
Optional.ofNullable(s).ifPresent(s2 -> System.out.println("executed"));
}
JDT 的 null 分析无法了解 JRE 和其他库中每个方法的语义。因此,看到对 ifPresent
的调用没有得出任何结论。这可以通过向 Optional
添加外部注释来补救,以便分析将方法 ofNullable
视为
<T> Optional<@NonNull T> ofNullable(@Nullable T value)
从 2015 年 6 月 24 日发布的 Eclipse Mars 开始支持外部注释。参见 Help: Using external null annotations。
问题中两个变体之间的差异是由于 null 分析如何与 Java8 类型推断相结合:在变体 (1) 中,s
具有类型 @Nullable String
。当在类型推断期间使用此类型时,得出的结论是 ifPresent
的参数也可以为空。在变体 (2) 中,s
具有类型 String
(尽管流分析可以看到它在 getSomeString
初始化后可能为 null)。未注释的类型 String
不够强大,无法帮助类型推断得出与变体 (1) 相同的结论(尽管这可能会在 JDT 的未来版本中得到改进)。
我是 Java 8 的新手,正在尝试 Null 类型注释和 Optional。
对于我下面的示例,我使用了 String 而不是我的 class 并且我调用 toUpperCase 只是为了调用一些东西,在我的例子中我实际上调用了一个传递参数的函数(所以不要认为我可以使用 :: operator and/or maps).
在 Eclipse 中,我打开了 Java - 编译器 - Errors/Warnings - 空分析错误。
我的测试代码如下:
public void test1(@Nullable String s) {
// the 2nd s2 has a Potential null pointer access error.
// I was hoping ifPresent would imply NonNull
Optional.ofNullable(s).ifPresent(s2 -> s2.toUpperCase());
}
@Nullable
public String getSomeString() {
return null;
}
public void test2() {
String s = getSomeString();
// This is fine, unlike the first example, I would have assumed that
// it would know s was still nullable and behave the same way.
Optional.ofNullable(s).ifPresent(s2 -> s2.toUpperCase());
}
似乎使用 Eclipse 类型空注释和 Optional.ifPresent 不能很好地结合在一起。
我是在浪费时间尝试让这样的东西工作吗?我是否应该恢复为将 getter 分配给临时变量然后检查是否为 null,如果不是则调用我的函数?
首先:@Nullable
接缝不属于 public Java 8 SDK。查看您导入的包:com.sun.istack.internal.Nullable
.
其次:我有 运行 你的两种方法:test1(null)
和 test2()
并且没有发生任何异常情况。一切都很好(正如预期的那样)。那么你观察到了什么?
运行 test1(null)
=> 没有执行 lambda 表达式。
运行 test2() => 没有执行 lambda 表达式。
我按照以下方式更改了您的测试代码:
public void test1(@Nullable String s) {
Optional.ofNullable(s).ifPresent(s2 -> System.out.println("executed"));
}
public void test2() {
String s = getSomeString();
Optional.ofNullable(s).ifPresent(s2 -> System.out.println("executed"));
}
JDT 的 null 分析无法了解 JRE 和其他库中每个方法的语义。因此,看到对 ifPresent
的调用没有得出任何结论。这可以通过向 Optional
添加外部注释来补救,以便分析将方法 ofNullable
视为
<T> Optional<@NonNull T> ofNullable(@Nullable T value)
从 2015 年 6 月 24 日发布的 Eclipse Mars 开始支持外部注释。参见 Help: Using external null annotations。
问题中两个变体之间的差异是由于 null 分析如何与 Java8 类型推断相结合:在变体 (1) 中,s
具有类型 @Nullable String
。当在类型推断期间使用此类型时,得出的结论是 ifPresent
的参数也可以为空。在变体 (2) 中,s
具有类型 String
(尽管流分析可以看到它在 getSomeString
初始化后可能为 null)。未注释的类型 String
不够强大,无法帮助类型推断得出与变体 (1) 相同的结论(尽管这可能会在 JDT 的未来版本中得到改进)。