Java 可选类型返回空值
我有一节这样的课Java 可选类型返回空值,java,nullpointerexception,null,optional,Java,Nullpointerexception,Null,Optional,我有一节这样的课 public class SomeClass { private Optional<String> testString; public SomeClass() { populateFields(); } public Optional<String> getTestString() { return testString; } private void populateFields() {
public class SomeClass {
private Optional<String> testString;
public SomeClass() {
populateFields();
}
public Optional<String> getTestString() {
return testString;
}
private void populateFields() {
if(//something is going false here){
testString = functionThatReturnsOptionalString();
}
}
}
公共类SomeClass{
私有可选测试字符串;
公共类(){
populateFields();
}
公共可选getTestString(){
返回testString;
}
私有void populateFields(){
如果(//此处出现错误){
testString=返回soOptionalString()的函数;
}
}
}
现在instanceOfSomeClass.getTestString()返回null。Optional不应该总是包含非null值或为空吗?我正在尝试或避免使用isNull()并在调用方中使用isEmpty()
如果我在populateFields()的第一行上放置一个断点,并在当时检查testString中的值,它会将该值显示为null。这意味着此字段的默认值(在分配任何内容之前)为空
请说明这种情况;以及oracle文档中可选类型的正确用法?: 可以包含或不包含非空值的容器对象 因此,如果变量设置为null,则返回null。
更多信息可选值始终包含非null值或为空,是的,但您没有可选值,您有一个指向null的可选类型引用。您需要初始化
testString
,例如初始化为Optional.empty()
Optional
不是魔术,它是一个与任何其他对象一样的对象,Optional
引用本身可以为空。可选的内容不能为空。来自Java文档:
可以包含或不包含非空值的容器对象。如果
值存在,isPresent()将返回true,get()将返回
价值
尽管YourClass的构造函数没有实例化可选类,这也是它为null的原因
public SomeClass() {
this.testString = Optional.empty();
}
来源:这是因为您首先需要一个类为Optional
的对象,并且代码只有一个类型为Optional
的引用,只要您不初始化它,它就是null
。用空/不存在的值按以下方式声明(并初始化)testString
:
private Optional<String> testString= Optional<String>.empty() ;
如果您已经有了一个字符串
值作为开始(我们称之为originalString
),那么有3个主要选项:
使用private Optional testString=Optional.of(originalString)初始化testString
(如果originalString
为null
,则会产生NullPointerException
)
使用Optional.ofNullable(originalString)
,如果originalString
为null,则生成空的/不存在的Optional
通过前面两个方法之一直接参考方法getTestString
中的originalString
(return Optional.ofNullable(originalString);
)。不需要testString
成员。实际上,我并不推荐这种做法
底线是,虽然实际的可选
对象不能包含null
值,但对可选
的引用肯定可以(尤其是在未初始化时)。根据经验,Optional
引用应始终使用Optional.empty()
初始化,如果不是实际的“present”/“non-empty”值。我总是喜欢将类的内部字段存储为它们的实际值,并在getter方法中使用return Optional.ofNullable(theField)
。这确保该方法始终返回某种类型的可选值。换句话说,您永远不会遇到这样的情况:本应返回optional的方法返回null
因此,在你的情况下:
private String testString;
...
public Optional<String> getTestString() {
return Optional.ofNullable(testString);
}
私有字符串testString;
...
公共可选getTestString(){
返回可选的.ofNullable(testString);
}
除了“永不返回null”的好处之外,当使用Gson之类的东西将类的实例封送为JSON之类的格式时,这种方法也应该更加规范。我没有用Java8 optionals尝试过Gson,但是使用Guava optionals,如果没有类型适配器,它们无法很好地序列化为JSON。如果您存储原始值,然后在getter方法中用Optional包装它们,它们将以您期望的方式序列化为JSON。您可以初始化testString
:private Optional testString=new Optional…
@helpYou-或者更确切地说,使用静态工厂方法:Optional.缺席()
如果您使用的是Guava optionals或Java 8 optionals的Optional.empty()
。Optional没有特殊的魔力-它是一个与其他任何类一样的类。这意味着可选引用(与所有引用一样)的默认值为null。Optional
不公开构造函数;您不能执行newoptional
。这意味着我应该首先将returnsooptionalstring()函数返回的可选值转换为字符串。所以它就像可选的字符串一样。这是个好主意吗?好吧,这取决于使用情况。在我的方法中增加了一个对象创建步骤。在99.99%的情况下使用这种方法,这并不重要,但是如果您在对性能非常敏感的情况下每秒调用此方法1000次,这种方法可能会太昂贵。如果您确实存在对性能敏感的情况,请定义最低性能阈值,并对这两种方法进行测量,以查看是否有性能原因不这样做。但很有可能,你不应该被PerformanceAnks的狗禁止。这是一个大数据环境,该代码是批处理程序的一部分,该批处理程序每天运行和处理约600万条记录(目前)。在这种情况下,我应该倾向于使用可选的.empty()?是否正在为所有这些记录调用该方法?D
private var testString= Optional.empty<String>() ;
private String testString;
...
public Optional<String> getTestString() {
return Optional.ofNullable(testString);
}