java 可选类型返回空值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28821435/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Optional Type returns a null value
提问by Gadam
I have a class like this.
我有一堂这样的课。
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();
}
}
}
Now instanceOfSomeClass.getTestString() returns null. Isn't Optional always supposed to contain a non-null value or be empty? I am trying or avoid isNull() and just use isEmpty() in my caller.
现在 instanceOfSomeClass.getTestString() 返回 null。Optional 不是总是应该包含非空值或为空吗?我正在尝试或避免 isNull() 并且只在我的调用者中使用 isEmpty() 。
If I put a breakpoint on the first line of populateFields() and check the value in testString at that time, it shows the value as null. Meaning the default value for this field(before being assigned anything) is null.
如果我在 populateFields() 的第一行放置一个断点并检查当时 testString 中的值,它会将该值显示为 null。这意味着此字段的默认值(在分配任何内容之前)为空。
Please shed light on this situation; and maybe the correct usage of Optional?
请阐明这种情况;以及 Optional 的正确用法?
回答by Louis Wasserman
An Optional always contains a non-null value or is empty, yes, but you don't have an Optional, you have a reference of type Optional pointing to null. You need to initialize testString
, e.g. to Optional.empty()
.
一个 Optional 总是包含一个非空值或者是空的,是的,但是你没有一个 Optional,你有一个指向 null 的 Optional 类型的引用。您需要初始化testString
,例如到Optional.empty()
。
Optional
isn't magic, it's an object like any other, and the Optional
reference itself can be null. It's the contents of the Optional
that can't be null.
Optional
不是魔法,它是一个像任何其他对象一样的对象,并且Optional
引用本身可以为空。它的内容Optional
不能为空。
回答by Dogs
I always like to store the internal fields of the class as their actual values, and use return Optional.ofNullable(theField)
in the getter method. This ensures that the method will always return some type of optional. In other words, you never run into the situation where your method which is supposed to return an optional is returning null.
我总是喜欢将类的内部字段存储为它们的实际值,并return Optional.ofNullable(theField)
在 getter 方法中使用。这确保该方法将始终返回某种类型的可选。换句话说,您永远不会遇到应该返回可选项的方法返回空值的情况。
So in your case:
所以在你的情况下:
private String testString;
...
public Optional<String> getTestString() {
return Optional.ofNullable(testString);
}
In additional to the 'never returning null' benefit, this approach should also be more behaved when using things like Gson to marshal instances of your class into a format like JSON. I haven't tried Gson with Java 8 optionals, but with Guava optionals they don't serialize very nicely into JSON without a type adapter. If you're storing the raw value and then wrapping them with Optionals at your getter methods, they serialize into JSON in just the manner you would expect.
除了“永不返回空值”的好处之外,当使用 Gson 之类的东西将类的实例编组为 JSON 之类的格式时,这种方法也应该更有效。我还没有尝试过使用 Java 8 选项的 Gson,但是使用 Guava 选项,它们在没有类型适配器的情况下不能很好地序列化为 JSON。如果您存储原始值,然后在您的 getter 方法中使用 Optionals 包装它们,它们就会以您期望的方式序列化为 JSON。
回答by Samuel Rondeau-Millaire
回答by Quanturium
From the Java documentation:
从 Java 文档:
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
可能包含也可能不包含非空值的容器对象。如果存在值,isPresent() 将返回 true,get() 将返回该值。
Although the constructor of YourClass does not instantiate your Optional class which is why it is null.
尽管 YourClass 的构造函数没有实例化您的 Optional 类,这就是它为空的原因。
public SomeClass() {
this.testString = Optional.empty();
}
source: http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
来源:http: //docs.oracle.com/javase/8/docs/api/java/util/Optional.html
回答by Mario Rossi
That's because your first need an objectof class Optional<String>
and the code has only a referenceof type Optional<String>
. Declare (and initialize) testString
in the following way:
那是因为您首先需要一个class对象,Optional<String>
而代码只有一个type引用Optional<String>
。testString
按以下方式声明(并初始化):
private Optional<String> testString= new Optional<String>() ;
Or using "diamond notation":
或使用“钻石符号”:
private Optional<String> testString= new Optional<>() ;
Now you have an Optional
!
现在你有了Optional
!