Java采用不同的方法来处理null和new
好的,我有一个关于处理空值的问题。这个问题很大程度上是基于观点,所以我想问一下赞成和反对的意见 假设我有一个可以返回null的函数,或者JSONArray。我总是想要一个JSONArray,所以如果函数的结果为null,我希望它创建一个空的JSONArray 目前我有以下方法:Java采用不同的方法来处理null和new,java,null,Java,Null,好的,我有一个关于处理空值的问题。这个问题很大程度上是基于观点,所以我想问一下赞成和反对的意见 假设我有一个可以返回null的函数,或者JSONArray。我总是想要一个JSONArray,所以如果函数的结果为null,我希望它创建一个空的JSONArray 目前我有以下方法: jsonArray = jsonArray==null?new JSONArray():jsonArray; 我喜欢这种方法,因为它只有一行,而且非常清楚它的作用。这确实让我想到了一个问题,这是否有效?我的想法是,现在
jsonArray = jsonArray==null?new JSONArray():jsonArray;
我喜欢这种方法,因为它只有一行,而且非常清楚它的作用。这确实让我想到了一个问题,这是否有效?我的想法是,现在它将在不需要时执行jsonArray=jsonArray
。虽然这似乎确实节省了一次跳转,但是如果(jsonArray==null)
处理空值的不同方法的优点是什么?您看过Java 8的
可选类了吗?这是一个对象包装器,允许您以函数方式处理null
例如,如果您有一个方法publicJSONArray getArray()
,希望总是返回null以外的值,则可以使用您的代码。使用“可选”,它将更改为:
public Optional<JSONArray> getArray() {
// jsonArray comes from somewhere
return Optional.ofNullable(jsonArray);
}
你把它换成
getArray().ifPresent(array -> // do something);
这意味着您不需要创建空的JSONArray、列表、集合、字符串等。在包装对象实际为空的情况下,将从Optional.ofNullable
返回一个单例可选项,从而进一步减少开销
如果你仍然想采用经典的方法,那也是可能的。由于if(option==null)
的计算结果应始终为false
(如果返回null而不是可选值,则有点忽略了要点!),因此您应该使用if(option.isPresent())
如果您没有使用Java8,您可以编写自己的可选库,或者使用第三方库,如Guava
编辑:非Java8解决方案
解决方案1
用番石榴之类的东西-看看
解决方案2
写你自己的!在此实现中,供应商
、消费者
和谓词
是返回、接受或测试对象的接口
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();
}
}
}
公共抽象类选项实现Iterable{
私有静态最终选项NONE=new NONE();
私人选择权(){
//无操作
}
公共静态选项(T){
返回t==null?无:新的部分(t);
}
公共静态选项empty(){
不返回任何值;
}
公共抽象得不到();
公共摘要T-orElse(T回退);
公共摘要T orElse(供应商);
公开摘要T或ROW(供应商除外供应商)E;
公共抽象布尔值isPresent();
公共抽象选项过滤器(谓词);
公开摘要无效(消费者);
公共抽象选项ifPresent(函数);
私有静态最终类的一些扩展选项{
私人最终T值;
私有部分(最终T值){
这个值=值;
}
@凌驾
公共部门得不到{
返回值;
}
@凌驾
公共T-orElse(最终T回退){
返回值;
}
@凌驾
公共T-orElse(最终供应商){
返回值;
}
@凌驾
公共T或ROW(最终供应商例外供应商)E{
返回值;
}
@凌驾
公共布尔值isPresent(){
返回true;
}
@凌驾
公共选项筛选器(最终谓词){
返回谓词。测试(值)?此
:无;
}
@凌驾
公共无效ifPresent(最终消费者){
消费者。消费(价值);
}
@凌驾
公共选项ifPresent(最终功能){
返回选项.of(function.apply(value));
}
@凌驾
公共迭代器迭代器(){
返回Collections.singletonList(value.iterator();
}
}
私有静态最终类None扩展选项{
@凌驾
公共部门得不到{
抛出新的IllegalStateException(“未定义值”);
}
@凌驾
公共T-orElse(最终T回退){
返回回退;
}
@凌驾
公共T-orElse(最终供应商){
返回供应商。get();
}
@凌驾
公共T或ROW(最终供应商例外供应商)E{
抛出异常supplier.get();
}
@凌驾
公共布尔值isPresent(){
返回false;
}
@凌驾
公共选项筛选器(最终谓词){
归还这个;
}
@凌驾
公共无效ifPresent(最终消费者){
//无操作
}
@凌驾
公共选项ifPresent(最终功能){
不返回任何值;
}
@凌驾
公共迭代器迭代器(){
返回集合.emptyList().iterator();
}
}
}
不幸的是,JSONArray
是可变的,否则您可以对每个将null
替换为空实例的情况使用相同的空实例。但我认为这在实践中不会有太大的区别,除非您将应用程序的所有其他部分都调整到最高性能。您是否有证据表明将jsonArray
分配给自身的成本在任何方面都是巨大的?(请注意,这并不是真的保存跳转,因为您仍然有一个条件,只是以不同的方式表示……0为什么不首先使该方法不能返回null?@DaniëlvandenBerg现在这是一个坏主意。无论您指的是null
,还是完全不使用s。混合使用多种方法可能接受或不接受/发出空值是一种测试
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();
}
}
}