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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 14:14:15  来源:igfitidea点击:

Optional Type returns a null value

javanullpointerexceptionnulloptional

提问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()

Optionalisn't magic, it's an object like any other, and the Optionalreference itself can be null. It's the contents of the Optionalthat 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

From the oracle documentation for the Optional type :

来自 Optional 类型的 oracle 文档:

A container object which may or may not contain a non-null value.

可能包含也可能不包含非空值的容器对象。

So, yes it will return null if the variable is set to null. More info here

因此,是的,如果变量设置为 null,它将返回 null。更多信息在这里

回答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) testStringin 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