好的,我有一个关于处理空值的问题。这个问题在很大程度上取决于意见,因此我将询问利弊。
假设我有一个可以返回 null 或 JSONArray 的函数。我一直想要一个 JSONArray,所以我希望它在函数的结果为 null 时创建一个空的。
目前我有以下方法:
jsonArray = jsonArray==null?new JSONArray():jsonArray;
我喜欢这种方法,因为它是一条线,而且非常清楚它的作用。这确实让我想到了一个问题,这有效吗?我的想法是,现在它会在不需要时执行 jsonArray = jsonArray
。尽管这似乎确实节省了您使用 if (jsonArray == null)
不同的 null 处理方式有哪些优势?
最佳答案
您看过 Java 8 的 Optional
类吗?这是一个对象包装器,可让您以功能性方式处理 null。
例如,如果您有一个方法 public JSONArray getArray()
希望始终返回 null 以外的内容,则可以使用您的代码。使用 Optional,它会变成这样:
public Optional<JSONArray> getArray() {
// jsonArray comes from somewhere
return Optional.ofNullable(jsonArray);
}
在 jsonArray 为 null 的情况下,optional 将为空;在它不为 null 的情况下,它将包含 jsonArray。
然后您可以将空检查替换为可选项指定的行为。而不是
JSONArray array = getArray();
if (array != null) {
// do something
}
你把它换成
getArray().ifPresent(array -> // do something);
这意味着您不需要创建空的 JSONArray、列表、集合、字符串等。在包装对象实际上为 null 的情况下,从 Optional.ofNullable
返回一个单例 Optional,进一步减少开销。
如果您仍然想采用经典方法,那也是可能的。因为 if (option == null)
应该总是评估为 false
(如果你返回 null 而不是一个 Optional,你有点错过了重点!),你会使用 if (option.isPresent())
.
如果您不使用 Java 8,您可以编写自己的 Optional 或使用第三方库,例如 Guava。
编辑:非 Java 8 解决方案
方案一
使用类似 Guava 的东西 - 看看 http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html
解决方案2
自己写!在此实现中,Supplier
、Consumer
和Predicate
是返回、接受或测试对象的接口(interface)。
public abstract class Option<T> implements Iterable<T> {
private static final Option NONE = new None();
private Option() {
// no-op
}
public static <T> Option<T> of(T t) {
return t == null ? NONE : new Some<T>(t);
}
public static <T> Option<T> empty() {
return NONE;
}
public abstract T get();
public abstract T orElse(T fallback);
public abstract T orElse(Supplier<T> supplier);
public abstract <E extends Exception> T orThrow(Supplier<E> exceptionSupplier) throws E;
public abstract boolean isPresent();
public abstract Option<T> filter(Predicate<T> predicate);
public abstract void ifPresent(Consumer<T> consumer);
public abstract <O> Option<O> ifPresent(Function<T, O> function);
private static final class Some<T> extends Option<T> {
private final T value;
private Some(final T value) {
this.value = value;
}
@Override
public T get() {
return value;
}
@Override
public T orElse(final T fallback) {
return value;
}
@Override
public T orElse(final Supplier<T> supplier) {
return value;
}
@Override
public <E extends Exception> T orThrow(final Supplier<E> exceptionSupplier) throws E {
return value;
}
@Override
public boolean isPresent() {
return true;
}
@Override
public Option<T> filter(final Predicate<T> predicate) {
return predicate.test(value) ? this
: NONE;
}
@Override
public void ifPresent(final Consumer<T> consumer) {
consumer.consume(value);
}
@Override
public <O> Option<O> ifPresent(final Function<T, O> function) {
return Option.of(function.apply(value));
}
@Override
public Iterator<T> iterator() {
return Collections.singletonList(value).iterator();
}
}
private static final class None<T> extends Option<T> {
@Override
public T get() {
throw new IllegalStateException("value not defined");
}
@Override
public T orElse(final T fallback) {
return fallback;
}
@Override
public T orElse(final Supplier<T> supplier) {
return supplier.get();
}
@Override
public <E extends Exception> T orThrow(final Supplier<E> exceptionSupplier) throws E {
throw exceptionSupplier.get();
}
@Override
public boolean isPresent() {
return false;
}
@Override
public Option<T> filter(final Predicate<T> predicate) {
return this;
}
@Override
public void ifPresent(final Consumer<T> consumer) {
// no-op
}
@Override
public <O> Option<O> ifPresent(final Function<T, O> function) {
return NONE;
}
@Override
public Iterator<T> iterator() {
return Collections.<T>emptyList().iterator();
}
}
}
关于Java 处理 if null then new 的不同方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32988485/