Java 8 Optional正确使用姿势
在Java程序中,空指针异常(NullPointerException)可以说是最常见的的了,所以我们在打代码的时候会到处使用if(null == A){ ...... }这类操作。Java 8提供了Optional类型来一定程度上缓解NPE问题,这里主要因为自己在使用Optional类型时候踩到一些坑,故作此总结加深印象。
Optional是什么
Optional是什么?有什么作用?什么时候该用?什么时候最好不用?这里我也不去网上搜索搬定义了,直接读源码类上的注释说明就可以明白了
package java.util; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Stream; /** ----Optional是什么---- * A container object which may or may not contain a non-{@code null} value. * If a value is present, {@code isPresent()} returns {@code true}. If no * value is present, the object is considered empty and * {@code isPresent()} returns {@code false}. * ----Optional的附加方法说明---- *
Additional methods that depend on the presence or absence of a contained * value are provided, such as {@link #orElse(Object) orElse()} * (returns a default value if no value is present) and * {@link #ifPresent(Consumer) ifPresent()} (performs an * action if a value is present). * ----什么时候不该用Optional---- *
This is a value-based * class; use of identity-sensitive operations (including reference equality * ({@code ==}), identity hash code, or synchronization) on instances of * {@code Optional} may have unpredictable results and should be avoided. * ----什么时候用Optional---- * @apiNote * {@code Optional} is primarily intended for use as a method return type where * there is a clear need to represent "no result," and where using {@code null} * is likely to cause errors. A variable whose type is {@code Optional} should * never itself be {@code null}; it should always point to an {@code Optional} * instance. * * @param
the type of value * @since 1.8 */
正确使用姿势
1 使用Optional 的目的主要是为了清晰地表达返回值中没有结果的可能性
所以一般只用来作为方法的返回值类型,例如:
Optional 是不可变类型,是加了final修饰的类,并且,它是没用共有构造器的,所以我们没办法new出一个Optional 来,我们只能使用它所提供的三个方法来得到Optional 对象:
// 1
public static Optional empty() {
@SuppressWarnings("unchecked")
Optional t = (Optional) EMPTY;
return t;
}
// 2
public static Optional of(T value) {
return new Optional<>(Objects.requireNonNull(value));
}
// 3
public static Optional ofNullable(T value) {
return value == null ? (Optional) EMPTY
: new Optional<>(value);
}
下面是个人对Optional 使用的一些总结:
2 不要直接给Optional 赋null值
3 如果不能保证对象一定不为null,那就用Optional .ofNullable(),因为Optional .of()会抛NPE
/**
* Returns an {@code Optional} describing the given non-{@code null}
* value.
*
* @param value the value to describe, which must be non-{@code null}
* @param the type of the value
* @return an {@code Optional} with the value present
* @throws NullPointerException if value is {@code null} //这里明确了value为空会NPE!!!
*/
public static Optional of(T value) {
return new Optional<>(Objects.requireNonNull(value));
}
/**
* Returns an {@code Optional} describing the given value, if
* non-{@code null}, otherwise returns an empty {@code Optional}.
*
* @param value the possibly-{@code null} value to describe
* @param the type of the value
* @return an {@code Optional} with a present value if the specified value
* is non-{@code null}, otherwise an empty {@code Optional}
*/
@SuppressWarnings("unchecked")
public static Optional ofNullable(T value) {
return value == null ? (Optional) EMPTY
: new Optional<>(value);
}
4 使用isEmpty()或isPresent()来作为判断value是否为空,而不是if(optional1 == null) {...}
5 使用orElse, orElseGet, orElseThrow这几个API来避免自己写if else语句
6 使用equals方法判断Optional对象是否相等,而不是使用“==”
因为Optional类已经覆盖了equals方法,所以想必你已经能猜到上面的输出结果了吧
7 使用filter对value对象做业务逻辑判断
首先我们在Shop类中加个如下简单的业务逻辑判断方法,然后再进行测试看看结果:
//在Shop类中加个简单的业务逻辑判断方法
public Boolean isRecommanded(){
if (Objects.equals(this.shopId,1L)){
return true;
}
return false;
}
如果提供给filter中的返回false,那么就会得到一个空的Optional,而这时再调用get方法就会报如上错误,所以在使用Optional的get方法前一定要使用isPresent()方法先判断!
以上就是个人对Optional学习和使用的一些总结,以此文记录一番
另外附上一个对stream使用总结得很好很全面的文章引用链接:https://mp.weixin.qq.com/s/UDBleuSVE-Yj6_p6R4o1bg