Langage de programmation Java
Java est un langage de programmation orienté objet qui peut écrire des logiciels d'application multiplateformes. Il s'agit d'un langage de programmation Java et d'une plate-forme Java lancés par Sun Microsystems en mai 1995. (C'est-à-dire que le nom général de JavaEE(j2ee), JavaME(j2me), JavaSE(j2se)).
Nous savons que Java 8 a ajouté des API très utiles, dont l'une est facultative. Si vous ne l'explorez pas un peu, vous pensez simplement que c'est possible. résoudre élégamment le problème NullPointException, donc le code a commencé à être écrit comme ceci
Optional<User> user = …… if (user.isPresent()) { return user.getOrders(); } else { return Collections.emptyList(); }
Ensuite, nous devons dire que notre réflexion est toujours au même endroit, mais nous pensons instinctivement que ce n'est qu'un wrapper pour l'instance User, qui est différente de ce que nous avons écrit auparavant 🎜>
User user = ….. if (user != null) { return user.getOrders(); } else { return Collections.emptyList(); }
Lors de l'appel de la méthode isPresent()
Lors de l'appel de la méthode get()
Lorsque le type facultatif est utilisé comme attribut de classe/instance
Lorsque le type facultatif est utilisé comme paramètre de méthode
isPresent() n'a aucune différence avec obj != null, et nos vies sont toujours choquantes à chaque étape. Cependant, les appels get() sans isPresent() le feront. recevoir des avertissements dans IntelliJ IDEA
L'utilisation de types facultatifs comme attributs ou paramètres de méthode est fortement déconseillée dans IntelliJ IDEAReports 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() 将会抛出一个异常)
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 Facultatif map(Function super T, ? extends U> mapper)
public T ouElse(T autre )
public T orElseGet(Fournisseur extends T> autre)
public void ifPresent(Consumer super T> consommateur)
public Facultatif
public Facultatif flatMap (Fonction super T, Facultatif> mapper)
public
Tout d'abord, je dois mentionner les trois méthodes de construction de Optionnel : Optionnel.of(obj), Optionnel.ofNullable (obj) et l'expliciteOptional.empty()
Optional.of(obj) : il nécessite que l'obj entrant ne puisse pas être une valeur nulle, sinon vous obtiendrez une NullPointerException avant d'entrer dans le rôle.
Optional.ofNullable( obj) : Il construit une instance Facultative de manière intelligente et tolérante. Tous les arrivants sont les bienvenus. Passez null et obtenez Optionnel.empty(). Si ce n'est pas null, appelez Optionnel.of(obj). .
Est-ce que cela signifie que nous devons simplement utiliser Optionnel.ofNullable(obj) une fois pour toutes, et construire l'instance Optionnelle d'une manière qui ne change pas et s'adapte au deuxième changement ? Dans ce cas, sinon pourquoi Option.of(obj) devrait-il être exposé comme ceci ? Privé Est-ce possible ?
Mon point de vue personnel est le suivant : 1. Quand nous sommes très, très clairs sur le fait que le paramètre obj doit être transmis toOptional.of(obj) ne peut pas être nul, par exemple, c'est un objet qui vient d'être nouveau (Optional.of(new User(...))), ou une constante non nulle; Nous voulons affirmer que obj n'est pas nul, c'est-à-dire que nous voulons signaler immédiatement une NullPointException au cas où obj est nul, immédiatement. Lors de la modification au lieu de masquer l'exception de pointeur nul, nous devons utiliser de manière décisiveOptional.of(obj) pour construire l'exception de pointeur nul. instance, sans permettre à aucune valeur nulle imprévisible de profiter de l'opportunité de se cacher dans l'option.
Commençons maintenant à utiliser une instance facultative existante. Supposons que nous ayons une instance d'utilisateur Facultatif
seront renvoyées si elle existe, sinon, une valeur par défaut. sera fourni
S'il existe, il sera renvoyé, sinon, il sera généré par une fonctionreturn 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)!