我应该为我的所有方法编写空检查吗?

问题描述 投票:1回答:3

为了学习目的,我正在创建自己的库,例如Apache Commons DigestUtils

在我的update()方法内部,我编写了一个简单的if (something == null) throw new Exception作为null检查。

/**
 * Performs a digest update for the {@code String} (converted to bytes using the
 * UTF-8 standard charsets) with a specific {@code MessageDigest} and returns
 * the final digest data.
 *
 *
 * @param messageDigest the {@code MessageDigest} with a specific algorithm to
 *                      process the digest.
 *
 * @param data          the data to digest.
 *
 * @return the {@code MessageDigest} with the processed update for the digest.
 *
 * @throws IllegalArgumentException if {@code messageDigest} is {@code null}.
 *
 * @throws IllegalArgumentException if {@code data} is {@code null}.
 */
public static MessageDigest update(final MessageDigest messageDigest, final String data) {
    if (messageDigest == null)
        throw new IllegalArgumentException("messageDigest cannot be null");
    if (data == null)
        throw new IllegalArgumentException("data cannot be null");

    messageDigest.update(data.getBytes(StandardCharsets.UTF_8));

    return messageDigest;
}

现在,我不确定是否应该在必须调用update()方法的其他方法中编写相同的检查,还是仅在该方法引发相应异常的注释中编写该检查。

public static byte[] digest(final MessageDigest messageDigest, final byte[] data) {
    return update(messageDigest, data).digest();
}

public static byte[] digest(final MessageDigest messageDigest, final byte[] data) {
    if (messageDigest == null)
        throw new IllegalArgumentException("messageDigest cannot be null");
    if (data == null)
        throw new IllegalArgumentException("data cannot be null");

    return update(messageDigest, data).digest();
}

请注意,digest()方法将调用update()方法。

最佳做法是什么?

java nullpointerexception throw
3个回答
0
投票

1。:有功能Objects.requireNonNull,正是此功能。如果给定参数等于Objects.requireNonNull,它将引发异常。

null

应该是

if (messageDigest == null)
        throw new IllegalArgumentException("messageDigest cannot be null");

2。:

由于Objects.requireNonNull(messageDigest, "messageDigest cannot be null"); 而引发异常的最佳实践是将其引发首先不应该出现null的地方。这是null背后的动机。

Fail Fast Principle引用应该出现在[[not

所在的位置时,您要在该位置确切地引发异常或处理该异常。您要将null参考传递给其他方法/功能。否则,当传递的null引用导致程序出现问题时,您将很难调试代码。这是因为不清楚null引用最初出现的位置。但是实际上caused是您要修复/处理的。一个例子:null
如果很明显public class Demo {
    public void a(Object obj) {
        b(obj);
    }
    private void b(Object obj) {
        c(obj);
    }
    private void c(Object obj) {
        // Calculation using obj.
    }
}
永远不应该传递a引用,那么这是检查它的正确位置。

null

[在每个方法中都进行public void a(Object obj) {
    Objects.requireNonNull(obj); // Throw exception when null.
    b(obj);
}
检查时很糟糕,因为对于所有这些方法而言null都不应该是obj的事实很重要,因此将null检查放在null的位置就足够了]不应放在首位,即null。程序应

快速失败

[a校验放在null中将更加糟糕,因为c在逻辑上永远不会从c接收到null引用,并且b不应从b接收到一个引用。如果a参考在null中引起问题,您将很难找出cnull中是否出现了b或调用了a的代码。您

想要

知道,因为您要修复出现的a引用的问题,因此不是所引起的问题。当然,有时您无法修复事件本身,但是您可以尝试尽可能地接近事件并减少由此造成的附带“损害”。
没有真正的转到null支票的方法。您必须将它们放置在正确的位置,以使程序

fail fast

出现的无效对象上。由您决定null检查的最佳位置在哪里,因为这完全取决于确切的情况。
我希望这可以为您提供一个很好的方法。

0
投票
更好的方法是让null方法执行此操作,如果它抛出update(),则也会抛出异常。有两个常见的事情要做,两者都抛出Exception,您也得到了一个。一种在方法名称中放置Exception的方法,其中throws SomeException是您要排除的SomeException

0
投票
  1. 从JDK15开始(或者已经是14)?系统本身抛出的NPE(即,当您运行时,说public static byte[] digest(final MessageDigest messageDigest, final byte[] data) throws IllegalArgumentException { try { return update(messageDigest, data).digest(); } catch(IllegalArgumentException e) { // Do whatever you want. You can even throw e if you want. } } 将具有所有详细信息;尤其是表达式的文本。这意味着如果在代码中NPE会“自然地”发生(因为您取消引用了该变量,或者将其传递给始终执行该操作的另一个方法),则无需进行空检查。您的代码,使其不必取消引用,您会失去调用该方法将导致null参数抛出的效果。需要记住的事情。
© www.soinside.com 2019 - 2024. All rights reserved.