我在Java中有以下代码:
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 null和if (back!=null)了。
所以这就是我得到的:
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,这被认为是一种糟糕的实践吗?
提前谢谢。
发布于 2019-05-21 17:15:51
使用Optional,您必须打开/测试Optional才能得到它,如果Optional没有正确使用(快速失败原则),您也会得到早期的空值异常。
例如:
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引用,这可能会使理解和解决问题更加复杂:
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) {
//...
}发布于 2019-05-21 16:55:18
第二种方法的一个稍微不同的变体可以更简洁地实现,如下所示:
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);
}
}https://stackoverflow.com/questions/56242995
复制相似问题