首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Null-Check & isPresent -不同的名称但问题相同?

Null-Check & isPresent -不同的名称但问题相同?
EN

Stack Overflow用户
提问于 2019-05-21 16:49:31
回答 2查看 66关注 0票数 2

我在Java中有以下代码:

代码语言:javascript
复制
public class Browser {

  public URL back() {
    try {
      //simulate: fetch last URL from Stack
      return Math.random() < 0.5 ? new URL("http://google.de") : null;
    } catch(MalformedURLException e) {
      return null;
    }
  }

  public void retrieveSite(URL url) {
    System.out.println(url);
    //...
  }

  public static void main(String[] args) {
    System.out.println("Normal back");
    Browser browser = new Browser();
    URL back = browser.back();
    if (back != null) browser.retrieveSite(back);
  }
}

我想了解更多关于Optional的知识,并重写这段代码,这样就不再需要return nullif (back!=null)了。

所以这就是我得到的:

代码语言:javascript
复制
public class Browser {

  Optional<URL> url = Optional.empty();

  public Optional<URL> back() {

    try {
      //simulate: fetch last URL from Stack
      if(Math.random()<0.5) {
        url = Optional.of(new URL("http://google.de"));
      } 
      return url;
    } catch(MalformedURLException e) {
      return url;
    }
  }

  public void retrieveSite(Optional<URL> url) {
    System.out.println(url);
    //...
  }

  public static void main(String[] args) {
    System.out.println("Normal back");
    Browser browser = new Browser();
    Optional<URL> back = browser.back();
    if(back.isPresent()) {
      browser.retrieveSite(back);
    }   
  }
}

现在,为了避免将空的Optional传递给retrieveSite,我必须检查当前值。但是,我从检查isPresent而不仅仅是!=null中究竟得到了什么呢?我是否应该返回一个default值,这样我就可以摆脱isPresent

另外,我还必须更改retrieveSite()的参数,以获取Optional,这被认为是一种糟糕的实践吗?

提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-21 17:15:51

使用Optional,您必须打开/测试Optional才能得到它,如果Optional没有正确使用(快速失败原则),您也会得到早期的空值异常。

例如:

代码语言:javascript
复制
  public static void main(String[] args) {
    System.out.println("Normal back");
    Browser browser = new Browser(); 
   // unwraping the optional or testing it is mandatory to get the object inside in
    browser.back().ifPresent(browser::retrieveSite); 
    // for example it will not compile
    browser.retrieveSite(browser.back()); 
    // of course you could cheat by invoking Optional.get() but that is a bad practice and the absence of object will be detected as soon as the invocation 
    browser.retrieveSite(browser.back().get()); 
  }

  public void retrieveSite(URL url) {
    //...
  }

如果没有Optional,如果客户忘记显式地检查无无效(url != null),那么NPE是可能的。对于开发人员来说,这种检查实际上不太令人信服,因为要获取/映射包装的对象,必须进行方法调用。此外,如果url参数在层中传递,您可以在非常底层的后面发现null引用,这可能会使理解和解决问题更加复杂:

代码语言:javascript
复制
  public static void main(String[] args) {
    System.out.println("Normal back");
    Browser browser = new Browser(); 
    // No unwrapping is necessary to get the url. 
    // So the robustness of the code depends on the developer habits
    browser.retrieveSite(browser.back());     
  }

  public void retrieveSite(URL url) {        
    //...
  }
票数 0
EN

Stack Overflow用户

发布于 2019-05-21 16:55:18

第二种方法的一个稍微不同的变体可以更简洁地实现,如下所示:

代码语言:javascript
复制
static class Browser {

    // good practice to return Optional instead of a null 
    Optional<URL> back() {
        try {
            //simulate: fetch last URL from Stack
            return Math.random() < 0.5 ? Optional.of(new URL("http://google.de")) : Optional.empty();
        } catch (MalformedURLException e) {
            return Optional.empty();
        }
    }

    // avoid using Optional as a parameter to a method
    static void retrieveSite(URL url) {
        System.out.println(url);
    }

    public static void main(String[] args) {
        System.out.println("Normal back");
        Browser browser = new Browser();
        // perform a void operation if the URL is present (consuming it)
        browser.back().ifPresent(Browser::retrieveSite);
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56242995

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档