为了学习目的,我正在创建自己的库,例如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()
方法。
最佳做法是什么?
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
中引起问题,您将很难找出c
或null
中是否出现了b
或调用了a
的代码。您想要
知道,因为您要修复出现的a
引用的问题,因此不是所引起的问题。当然,有时您无法修复事件本身,但是您可以尝试尽可能地接近事件并减少由此造成的附带“损害”。没有真正的转到null
支票的方法。您必须将它们放置在正确的位置,以使程序fail fast
出现的无效对象上。由您决定null
检查的最佳位置在哪里,因为这完全取决于确切的情况。我希望这可以为您提供一个很好的方法。null
方法执行此操作,如果它抛出update()
,则也会抛出异常。有两个常见的事情要做,两者都抛出Exception
,您也得到了一个。一种在方法名称中放置Exception
的方法,其中throws SomeException
是您要排除的SomeException
。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参数抛出的效果。需要记住的事情。