Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.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中方法调用前空检查的快捷方式_Java_Null - Fatal编程技术网

java中方法调用前空检查的快捷方式

java中方法调用前空检查的快捷方式,java,null,Java,Null,在编写简单或复杂的java代码时,像这样编写代码似乎很常见: if (obj != null) { obj.someMethod(); } public class NullHelper { private static <T> boolean check(T object) { return object == null; } public static <T> void nullOrExecute(T obj

在编写简单或复杂的java代码时,像这样编写代码似乎很常见:

if (obj != null) {
    obj.someMethod();
}
public class NullHelper
{
    private static <T> boolean check(T object)
    {
        return object == null;
    }

    public static <T> void nullOrExecute(T object, Consumer<T> func)
    {
        if (!check(object))
            func.accept(object);
    }

    public static <T, R> R nullOrCompute(T object, Function<T, R> func)
    {
        return check(object)
            ? null
            : func.apply(object);
    }

    public static <T, P0, R> R nullOrCompute(T object, BiFunction<T, P0, R> func, P0 param0)
    {
        return check(object)
            ? null
            : func.apply(object, param0);
    }

    // more params
}
或者更具体地说:

Foo someValue = null;
if (valueObject != null) {
    someValue = valueObject.getSomeValue();
}
这意味着当Value对象为null时,
someValue
将保持null。现在,由于我经常遇到这种类型的代码(它增加了认知/循环复杂性),我想知道是否有某种方法可以以任何方式简化这些语句。我寻找的解决方案如下所示:

Foo someValue = nullOrCompute(valueObject, valueObject::getSomeValue);
经过一些研究,Java似乎没有提供类似的功能。所以,作为一个测试,我自己写了一个快捷方式,如下所示:

if (obj != null) {
    obj.someMethod();
}
public class NullHelper
{
    private static <T> boolean check(T object)
    {
        return object == null;
    }

    public static <T> void nullOrExecute(T object, Consumer<T> func)
    {
        if (!check(object))
            func.accept(object);
    }

    public static <T, R> R nullOrCompute(T object, Function<T, R> func)
    {
        return check(object)
            ? null
            : func.apply(object);
    }

    public static <T, P0, R> R nullOrCompute(T object, BiFunction<T, P0, R> func, P0 param0)
    {
        return check(object)
            ? null
            : func.apply(object, param0);
    }

    // more params
}
公共类NullHelper
{
私有静态布尔检查(T对象)
{
返回对象==null;
}
公共静态无效nullOrExecute(T对象,使用者函数)
{
如果(!检查(对象))
函数接受(对象);
}
公共静态R nullOrCompute(T对象,函数func)
{
退货支票(对象)
无效的
:函数应用(对象);
}
公共静态R nullOrCompute(T对象,双函数函数func,P0参数0)
{
退货支票(对象)
无效的
:func.apply(对象,参数0);
}
//更多参数
}
请注意,如果您想包含具有更多参数的版本,则必须编写自己的“
nffunction
”接口,因为Java不提供
TriFunction
s或更高版本

我的问题是:

这段代码是简化现有大型代码库的好方法吗?如果不是,是因为我不知道有一个更方便的Java特性,还是因为我需要改进我的自定义版本(以及如何改进)

请记住,我说的不是一般最方便的解决方案,而是可以应用于现有大型代码库的解决方案

提前感谢。

请考虑使用而不是
null
来表示合法不存在的内容

Optional<Bar> valueObject = getValueObject();
Optional<Foo> someValue = valueObject.map(o -> o.getSomeValue());
但我认为您会发现,如果您以这种方式开始,那么
可选的
范例将随着时间的推移自然传播,并提高整个项目的代码质量。

考虑使用而不是
null
来表示合法不存在的内容

Optional<Bar> valueObject = getValueObject();
Optional<Foo> someValue = valueObject.map(o -> o.getSomeValue());
但我认为您会发现,如果您以这种方式开始,那么
可选的
范例将随着时间的推移而自然传播,并提高整个项目的代码质量。

您的代码:

check(foo)
nullOrExecute(foo, consumer)
nullOrCompute(foo, mapper)
nullOrCompute(foo, func, param)
使用选项的等效代码:

Optional.ofNullable(foo).isPresent();
Optional.ofNullable(foo).ifPresent(consumer);
Optional.ofNullable(foo).map(mapper)
您的代码:

check(foo)
nullOrExecute(foo, consumer)
nullOrCompute(foo, mapper)
nullOrCompute(foo, func, param)
使用选项的等效代码:

Optional.ofNullable(foo).isPresent();
Optional.ofNullable(foo).ifPresent(consumer);
Optional.ofNullable(foo).map(mapper)

可选
更快,允许链接不存在的字段

完全使用传统的可为空对象:

Foo someValue = Optional.ofNullable(valueObject).map(Bar::getSomeValue).orElse(null);
部分:

Optional<Foo> someValue = Optional.ofNullable(valueObject).map(Bar::getSomeValue);
Optional someValue=Optional.ofNullable(valueObject).map(Bar::getSomeValue);
移植到Optionals:

Optional<Foo> someValue = valueObject.map(Bar::getSomeValue);
可选someValue=valueObject.map(Bar::getSomeValue);
优点:

Optional<Baz> someValue = valueObject.map(Bar::getSomeValue).map(Fuz::getSub);

someValue.ifPresent(v -> ... non-null v);
可选someValue=valueObject.map(Bar::getSomeValue.map)(Fuz::getSub);
someValue.ifPresent(v->…非空v);

代码样式检查器现在可以很好地检测空值和非空值。还可以对非空值进行注释。您可以增量地移动到Optionals,就像您在扩展空处理中所希望的那样。

Optional
更快,并允许链接不存在的字段

完全使用传统的可为空对象:

Foo someValue = Optional.ofNullable(valueObject).map(Bar::getSomeValue).orElse(null);
部分:

Optional<Foo> someValue = Optional.ofNullable(valueObject).map(Bar::getSomeValue);
Optional someValue=Optional.ofNullable(valueObject).map(Bar::getSomeValue);
移植到Optionals:

Optional<Foo> someValue = valueObject.map(Bar::getSomeValue);
可选someValue=valueObject.map(Bar::getSomeValue);
优点:

Optional<Baz> someValue = valueObject.map(Bar::getSomeValue).map(Fuz::getSub);

someValue.ifPresent(v -> ... non-null v);
可选someValue=valueObject.map(Bar::getSomeValue.map)(Fuz::getSub);
someValue.ifPresent(v->…非空v);

代码样式检查器现在可以很好地检测空值和非空值。还可以对非空值进行注释。一个人可能会逐渐转向Optionals,正如您在扩展null处理中所希望的那样。

使用null“编写代码似乎很常见”。根本原因是您使用了NULL。这是一个面向对象的范例中的错误,应该不惜一切代价避免。@Boris所以你建议重构整个大型代码库以去除空值?当然,空值不是很好,但是在所有糟糕的面向对象实践中,这远远不是最糟糕的。NullPointerException是典型代码中最容易发现和解决的问题之一。@Malt没错,我不是在寻找完美的范例,而是寻找一个简单且可扩展的范例solution@RaphaelTarita我已经把我的2分钱放进了。。。这是不受欢迎的,只是需要考虑的想法。看一看,用NULL“编写代码”似乎很常见。根本原因是您使用了NULL。这是一个面向对象的范例中的错误,应该不惜一切代价避免。@Boris所以你建议重构整个大型代码库以去除空值?当然,空值不是很好,但是在所有糟糕的面向对象实践中,这远远不是最糟糕的。NullPointerException是典型代码中最容易发现和解决的问题之一。@Malt没错,我不是在寻找完美的范例,而是寻找一个简单且可扩展的范例solution@RaphaelTarita我已经把我的2分钱放进了。。。这是不受欢迎的,只是需要考虑的想法。OP指出它是一个很大的现有代码库,因此将每个方法的返回类型从
T
重写为
Optional
是非常困难的tedious@Tobilko没错。我知道Optional(以及使用像Rust这样的非空语言的好处),但在我看来,这可能是对大量代码库的太多重构,主要是因为如果你想正确地进行重构,问题会扩散,因此你必须在任何地方实现这项技术,你仍然可以在不改变方法签名的情况下利用Optional。使用
of nullable()
方法,您仍然可以将大多数空检查逻辑转换为一行程序,并使用比编写自己的实用程序更广泛接受的范例。我支持可选,+1。我