Heim  >  Artikel  >  Java  >  Korrekte Haltung für die Verwendung von Java8 Optional

Korrekte Haltung für die Verwendung von Java8 Optional

黄舟
黄舟Original
2017-01-18 15:24:461389Durchsuche

Java-Programmiersprache

Java ist eine objektorientierte Programmiersprache, die plattformübergreifende Anwendungssoftware schreiben kann. Es handelt sich um eine Java-Programmiersprache und Java-Plattform, die im Mai 1995 von Sun Microsystems eingeführt wurde. der allgemeine Name von JavaEE(j2ee), JavaME(j2me), JavaSE(j2se)).


Wir wissen, dass Java 8 einige sehr nützliche APIs hinzugefügt hat, von denen eine optional ist. Wenn Sie sich nicht ein wenig damit befassen, denken Sie nur leicht, dass dies möglich ist Lösen Sie das NullPointException-Problem elegant, sodass der Code so geschrieben wurde

Optional<User> user = ……
if (user.isPresent()) {
return user.getOrders();
} else {
return Collections.emptyList();
}

Dann müssen wir sagen, dass wir immer noch am selben Ort sind, aber wir denken instinktiv, dass es sich nur um einen Wrapper handelt die User-Instanz, die sich von dem unterscheidet, was wir zuvor geschrieben haben 🎜>

User user = …..
if (user != null) {
return user.getOrders();
} else {
return Collections.emptyList();
}
Es gibt im Wesentlichen keinen Unterschied. Dies ist die richtige Haltung für die Verwendung optionaler Java 8-Typen, über die wir sprechen werden.

Während der Olympischen Spiele in Rio wurde in den Nachrichten wiederholt die rote Fünf-Sterne-Flagge erwähnt. Es gibt ein Problem, aber ich kann nichts Falsches erkennen, egal wie ich es betrachte. Später fand ich heraus, dass die Haltung des kleinen Sterns, der das anbetet Das Zentrum ist falsch. Deshalb dürfen wir die Dinge, an die wir gewöhnt sind, nicht als selbstverständlich betrachten, und wir werden überhaupt nicht das Gefühl haben, dass etwas falsch ist. Mit anderen Worten: Wenn wir auf Java 8 Optional umsteigen, können wir nicht auf die Art und Weise erben, wie wir es tun Wir sollten die neue und korrekte Haltung der korrekten Verwendung von Java 8 Optional beherrschen. Apropos: Wenn wir Optional immer noch auf die folgende Weise verwenden, müssen wir anfangen, uns selbst zu überprüfen 🎜>

Beim Aufruf der isPresent()-Methode

Beim Aufruf der get()-Methode

Wenn der optionale Typ als Klassen-/Instanzattribut verwendet wird

Wenn Der optionale Typ wird als Methodenparameter verwendet

isPresent() hat keinen Unterschied zu obj != null, und unser Leben ist immer noch schockierend. Get()-Aufrufe ohne isPresent() werden jedoch Erhalten Sie Warnungen in IntelliJ IDEA

Von der Verwendung optionaler Typen als Attribute oder Methodenparameter wird in IntelliJ IDEA dringend abgeraten

Reports calls to java.util.Optional.get() without first checking with a isPresent() 
call if a value is available. If the Optional does not contain a value, get() will throw an exception. 
(调用 Optional.get() 前不事先用 isPresent() 检查值是否可用. 假如 Optional 不包含一个值, get() 将会抛出一个异常)
Was wir uns in Optional also wirklich verlassen können, sollte etwas anderes sein Methoden außer isPresent() und get():

public8f4f974c37a8b771235386e098482ce3 Optional8f4f974c37a8b771235386e098482ce3 map(Function4764c7d1113c2fd51056f1823c9f0318 Mapper)
Reports any uses of java.util.Optional<T>, java.util.OptionalDouble, java.util.OptionalInt, 
java.util.OptionalLong or com.google.common.base.Optional as the type for a field or a parameter. Optional was designed
 to provide a limited mechanism for library method return types where there needed to be a clear way to represent 
 “no result”. Using a field with type java.util.Optional is also problematic if the class needs to be Serializable, 
 which java.util.Optional is not. (使用任何像 Optional 的类型作为字段或方法参数都是不可取的. Optional 只设计为类库方法的,
  可明确表示可能无值情况下的返回类型. Optional 类型不可被序列化, 用作字段类型会出问题的)

public T orElse(T other )

public T orElseGet(Supplier71b63f436d94a50f17c5ed897161f1dd other)

public void ifPresent(Consumer< ;? super T> Consumer)

public Optional8742468051c85b06f0a0af9e3e506b5c filter( Prädikat117c5a0bdb71ea9a9d0c2b99b03abe3e Prädikat)

public8f4f974c37a8b771235386e098482ce3 flatMap(Function mapper)

public < ; T orElseThrow(Supplier

Optional.of(obj): Es erfordert, dass das eingehende obj kein Nullwert sein darf, sonst erhalten Sie eine NullPointerException, bevor Sie die Rolle betreten.

Optional.ofNullable( obj): Es erstellt eine optionale Instanz auf intelligente und tolerante Weise. Übergeben Sie null und erhalten Sie Optional.empty(). .

Bedeutet das, dass wir nur ein für alle Mal Optional.ofNullable(obj) verwenden und die optionale Instanz so konstruieren müssen, dass sie sich nicht ändert und sich an die zweite Änderung anpasst? Fall, warum sollte Optional.of(obj) sonst so offengelegt werden? Privat Ist das möglich?

Mein persönlicher Standpunkt ist: 1. Wenn uns sehr, sehr klar ist, dass der obj-Parameter übergeben werden muss to Optional.of(obj) kann beispielsweise nicht null sein, wenn es sich um ein Objekt handelt, das gerade neu war (Optional.of(new User(...))), oder wenn es eine Nicht-Null-Konstante 2 ist Wenn wir bestätigen möchten, dass obj nicht null ist, d Erstellen Sie die optionale Instanz, ohne zuzulassen, dass ein unvorhersehbarer Nullwert die Gelegenheit nutzt, sich in der optionalen Instanz zu verstecken.

Jetzt beginnen wir mit der Verwendung einer vorhandenen optionalen Instanz. Angenommen, wir haben einen optionalen Instanzbenutzer . Hier sind einige häufige Methoden, die vermieden werden sollten. if(user.isPresent()) { ... } else { ... } Mehrere Anwendungsmethoden werden zurückgegeben, wenn sie nicht vorhanden sind. Es wird ein Standardwert bereitgestellt

Wenn er vorhanden ist, wird er zurückgegeben, andernfalls wird er von einer Funktion generiert

return user.orElseGet(() -> fetchAUserFromDatabase()); //而不要 return user.isPresent() ? user: fetchAUserFromDatabase();

存在才对它做点什么

user.ifPresent(System.out::println);

//而不要下边那样
if (user.isPresent()) {
  System.out.println(user.get());
}

map 函数隆重登场

当 user.isPresent() 为真, 获得它关联的 orders, 为假则返回一个空集合时, 我们用上面的 orElse, orElseGet 方法都乏力时, 那原本就是 map 函数的责任, 我们可以这样一行

return user.map(u -> u.getOrders()).orElse(Collections.emptyList())

//上面避免了我们类似 Java 8 之前的做法
if(user.isPresent()) {
  return user.get().getOrders();
} else {
  return Collections.emptyList();
}

map  是可能无限级联的, 比如再深一层, 获得用户名的大写形式

return user.map(u -> u.getUsername())
           .map(name -> name.toUpperCase())
           .orElse(null);

这要搁在以前, 每一级调用的展开都需要放一个 null 值的判断

User user = .....
if(user != null) {
  String name = user.getUsername();
  if(name != null) {
    return name.toUpperCase();
  } else {
    return null;
  }
} else {
  return null;
}

针对这方面 Groovy 提供了一种安全的属性/方法访问操作符 ?.

user?.getUsername()?.toUpperCase();

Swift 也有类似的语法, 只作用在  Optional 的类型上.

用了 isPresent() 处理 NullPointerException 不叫优雅, 有了  orElse, orElseGet 等, 特别是 map 方法才叫优雅.

其他几个, filter() 把不符合条件的值变为 empty(),  flatMap() 总是与 map() 方法成对的,  orElseThrow() 在有值时直接返回, 无值时抛出想要的异常.

一句话小结: 使用 Optional 时尽量不直接调用 Optional.get() 方法, Optional.isPresent() 更应该被视为一个私有方法, 应依赖于其他像 Optional.orElse(), Optional.orElseGet(), Optional.map() 等这样的方法.

最后, 最好的理解 Java 8 Optional 的方法莫过于看它的源代码 java.util.Optional, 阅读了源代码才能真真正正的让你解释起来最有底气, Optional 的方法中基本都是内部调用  isPresent() 判断, 真时处理值, 假时什么也不做.

以上就是使用 Java8 Optional 的正确姿势的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:10 Lügen über JavaNächster Artikel:10 Lügen über Java