Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java采用不同的方法来处理null和new_Java_Null - Fatal编程技术网

Java采用不同的方法来处理null和new

Java采用不同的方法来处理null和new,java,null,Java,Null,好的,我有一个关于处理空值的问题。这个问题很大程度上是基于观点,所以我想问一下赞成和反对的意见 假设我有一个可以返回null的函数,或者JSONArray。我总是想要一个JSONArray,所以如果函数的结果为null,我希望它创建一个空的JSONArray 目前我有以下方法: jsonArray = jsonArray==null?new JSONArray():jsonArray; 我喜欢这种方法,因为它只有一行,而且非常清楚它的作用。这确实让我想到了一个问题,这是否有效?我的想法是,现在

好的,我有一个关于处理空值的问题。这个问题很大程度上是基于观点,所以我想问一下赞成和反对的意见

假设我有一个可以返回null的函数,或者JSONArray。我总是想要一个JSONArray,所以如果函数的结果为null,我希望它创建一个空的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();
        }
    }
}