我有一个这样的课。
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();
}
}
}
现在instanceOfSomeClass.getTestString()返回null。 Isn&t; t可选始终应该包含非空值或为空?我正在尝试或避免使用isNull()并在我的调用者中使用isEmpty()。
如果我在populateFields()的第一行放置一个断点并在那时检查testString中的值,它会将值显示为null。意味着此字段的默认值(在分配任何内容之前)为空。
请说明这种情况;也许正确使用Optional?
答案 0 :(得分:8)
Optional总是包含一个非null值或者为空,是的,但是你没有Optional,你有一个类型为Optional的引用为null。您需要初始化testString
,例如到Optional.empty()
。
Optional
不是魔术,它是一个像任何其他对象一样的对象,Optional
引用本身可以为null。这是Optional
的内容,不能为空。
答案 1 :(得分:1)
我总是喜欢将类的内部字段存储为实际值,并在getter方法中使用return Optional.ofNullable(theField)
。这可确保该方法始终返回某种类型的可选项。换句话说,您永远不会遇到应该返回可选项的方法返回null的情况。
所以在你的情况下:
private String testString;
...
public Optional<String> getTestString() {
return Optional.ofNullable(testString);
}
除了永远不会返回null&#39;好处,当使用像Gson这样的东西将类的实例编组为JSON这样的格式时,这种方法也应该更有表现力。我没有尝试过使用Java 8选项的Gson,但是使用Guava选项,他们不需要在没有类型适配器的情况下很好地序列化为JSON。如果您正在存储原始值,然后使用Optionals将它们包装在getter方法中,它们会按照您期望的方式序列化为JSON。
答案 2 :(得分:0)
答案 3 :(得分:0)
来自Java文档:
容器对象,可能包含也可能不包含非null值。如果一个 值存在,isPresent()将返回true,get()将返回 价值。
虽然YourClass的构造函数没有实例化您的Optional类,这就是它为null的原因。
public SomeClass() {
this.testString = Optional.empty();
}
来源:http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
答案 4 :(得分:0)
这是因为您首先需要类Optional<String>
的对象,并且代码只有类型Optional<String>
的引用。以下列方式声明(并初始化)testString
:
private Optional<String> testString= new Optional<String>() ;
或使用&#34;钻石符号&#34;:
private Optional<String> testString= new Optional<>() ;
现在你有一个Optional
!