我们应该总是在第一行检查java方法的每个参数是否为null吗?

发布于 2024-10-20 13:12:51 字数 334 浏览 2 评论 0原文

每个方法都接受一组参数值。我们应该始终验证输入参数的非空性还是允许代码因经典 RunTimeException 失败?

我见过很多代码,人们并没有真正检查输入参数的空性,而只是使用参数编写业务逻辑。最好的方法是什么?

void public( String a, Integer b, Object c)
{
  if( a == null || b == null || c == null)
  {
    throw new RunTimeException("Message...");
  }
  .....business logic.....
}

Every method accepts a set of parameter values. Should we always validate the non-nullness of input parameters or allow the code to fail with classic RunTimeException?

I have seen a lot of code where people don't really check the nullness of input parameters and just write the business logic using the parameters. What is the best way?

void public( String a, Integer b, Object c)
{
  if( a == null || b == null || c == null)
  {
    throw new RunTimeException("Message...");
  }
  .....business logic.....
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

层林尽染 2024-10-27 13:12:51

最好的方法是仅在必要时进行检查

例如,如果您的方法是私有,那么您知道没有其他人在使用它,并且您知道您没有传递任何空值,那么就没有必要再次检查。

如果您的方法是public,谁知道您的 API 的用户会尝试做什么,所以最好检查一下。

如果有疑问,请检查

但是,如果您能做的最好的事情就是抛出 NullPointerException,那么您可能不想检查。例如:

int getStringLength(String str) {
  return str.length();
}

即使您检查了 null,合理的选择是抛出 NullPointerExceptionstr.length() 会为您执行此操作无论如何。

The best way is to only check when necessary.

If your method is private, for example, so you know nobody else is using it, and you know you aren't passing in any nulls, then no point to check again.

If your method is public though, who knows what users of your API will try and do, so better check.

If in doubt, check.

If the best you can do, however, is throw a NullPointerException, then may not want to check. For example:

int getStringLength(String str) {
  return str.length();
}

Even if you checked for null, a reasonable option would be throwing a NullPointerException, which str.length() will do for you anyways.

谁与争疯 2024-10-27 13:12:51

不。标准假设参数不会为 null,否则将抛出 NullPointerException。如果您的方法允许参数为空,您应该在 api 中声明这一点。

No. It's standard to assume that parameters will not be null and that a NullPointerException will be thrown otherwise. If your method allows a parameter to be null, you should state that in your api.

勿忘初心 2024-10-27 13:12:51

Java 的一个不幸的方面是,引用可以为 null,并且无法在语言中指定它们不是 null。

所以一般来说是的,不要对 null 做出解释,也不要陷入稍后可能抛出 NPE 的情况。

JSR305(现已停用)允许您对参数进行注释以声明它们不应被赋予 null

void fn(@Nonnull String a, @Nonnull Integer b, @Nonnull Object c) {

冗长,但这就是适合您的 Java。还有其他注释库和检查器的功能大致相同,但不是标准的。

(关于大写的注意事项:当“non-thing”形式的驼峰式单词时, 标准 不会将路由单词大写,除非它是类的名称。因此 nonthingnonnull。)

除了运行检查器时之外,注释实际上也不会强制执行该规则。您可以静态地包含一个方法来进行检查:

public static <T> T nonnull(T value) {
    if (value == null) {
        throwNPE();
    }
    return value;
}
private static void throwNPE() {
    throw new NullPointerException();
}

在构造函数中返回值很方便:

import static pkg.Check.nonnull;

class MyClass {
    @Nonnull private final String thing;
    public MyClass(@Nonnull String thing) {
        this.thing = nonnull(thing);
    }
    ...

It's an unfortunate aspect of Java that references can be null and there is no way to specify in the language that they are not.

So generally yes, don't make up an interpretation for null and don't get into a situation where an NPE might be thrown later.

JSR305 (now inactive) allowed you to annotate parameters to state that they should not be given nulls.

void fn(@Nonnull String a, @Nonnull Integer b, @Nonnull Object c) {

Verbose, but that's Java for you. There are other annotation libraries and checkers that do much the same, but are non-standard.

(Note about capitalisation: When camel-casing words of the form "non-thing", the standard is not to capitalise the route word unless it is the name of a class. So nonthing and nonnull.)

Annotations also don't actually enforce the rule, other than when a checker is run. You can statically include a method to do the checking:

public static <T> T nonnull(T value) {
    if (value == null) {
        throwNPE();
    }
    return value;
}
private static void throwNPE() {
    throw new NullPointerException();
}

Returning the value is handy in constructors:

import static pkg.Check.nonnull;

class MyClass {
    @Nonnull private final String thing;
    public MyClass(@Nonnull String thing) {
        this.thing = nonnull(thing);
    }
    ...
脸赞 2024-10-27 13:12:51

我认为这样做没有多大意义。您只是简单地复制第一次尝试操作 abc 时免费获得的行为。

I don't see a great deal of point in doing this. You're simply replicating behaviour that you'd get for free the first time you try to operate on a, b or c.

穿透光 2024-10-27 13:12:51

这取决于您是否期望任何参数为 null - 更准确地说,如果某些参数为 null,您的方法是否仍然可以做出正确的决定。

如果没有,最好检查 null 并引发异常,因为否则您将得到一个 NullPointerException,您永远不应该捕获它,因为它的出现总是表明:您忘记检查代码中的变量。 (如果你抓住了它,你可能会错过它被抛出的其他事件,并且你可能会引入错误)。

另一方面,如果您抛出 RunTimeException 或其他自定义异常,您可以在上游的某个位置处理它,以便您可以更好地控制所发生的情况。

It depends if you expect any of your arguments to be null - more precisely, if your method can still make a correct decision if some parameters are null.

If not, it's good practice to check for null and raise an exception, because otherwise you'll get a NullPointerException, which you should never catch, as its appearance always indicates that you forgot to check your variables in your code. (and if you catch it, you might miss other occurrences of it being thrown, and you may introduce bugs).

On the other hand, if you throw RunTimeException or some other custom exception, you could then handle it somewhere on the upstream, so that you have more control over what goes on.

沉默的熊 2024-10-27 13:12:51

不,你不应该普遍这样做。

我的偏好按顺序是:

  1. 对 null 做一些明智的事情。明智的做法完全取决于具体情况,但抛出自定义异常不应该是您的首选。
  2. 使用断言检查 null 并进行彻底测试,消除任何产生 null 输入的情况 - 也称为错误。
  3. 对于公共 API,记录不允许 null 并让它因 NPE 失败。

No, you shouldn't do that universally.

My preferences, in order, would be:

  1. Do something sensible with the null. The sensible thing to do depends entirely on the situation, but throwing a custom exception should not be your first choice.
  2. Use an assertion to check for null and test thoroughly, eliminating any situations in which null input is produced since - a.k.a bugs.
  3. For public APIs, document that null isn't allowed and let it fail with an NPE.
萌︼了一个春 2024-10-27 13:12:51

是的,公共方法应该清理输入,特别是如果错误的输入可能会导致方法代码出现问题。快速失败是个好主意;即尽快检查。 Java 7 添加了一个新的 Objects 类,可以轻松检查 null 参数并包含自定义消息:

public final void doSomething(String s)
{
  Objects.requireNonNull(s, "The input String cannot be null");
  // rest of your code goes here...
}

这将引发 NullPointerException

Objects 类的 Javadoc: http://docs.oracle.com/javase/7/docs/api/java/util/Objects.html

Yes, public methods should scrub the input, especially if bad input could cause problems within your method's code. It's a good idea to fail fast; that is, check as soon as possible. Java 7 added a new Objects class that makes it easy to check for null parameters and include a customized message:

public final void doSomething(String s)
{
  Objects.requireNonNull(s, "The input String cannot be null");
  // rest of your code goes here...
}

This will throw a NullPointerException.

Javadocs for the Objects class: http://docs.oracle.com/javase/7/docs/api/java/util/Objects.html

霓裳挽歌倾城醉 2024-10-27 13:12:51

这取决于您的代码试图执行的操作以及您想要抛出异常的情况。有时,如果您的方法无法使用空值正常工作,您会希望您的方法始终抛出异常。如果您的方法可以解决空值,那么可能没有必要抛出异常。

添加太多检查异常可能会导致代码变得非常复杂。这就是它们没有包含在 C# 中的原因。

It depends on what your code is trying to do and the situation in which you want to throw an Exception. Sometime you will want your method to always throw an Exception if your method will not be able to work properly with null values. If your method can work around null values then its probably not necessary to throw an Exception.

Adding too many checked Exceptions can make for very convoluted and complicated code. This was the reason that they were not included in C#.

毁我热情 2024-10-27 13:12:51

永远不应该抛出运行时异常,除非它确实是系统运行的致命条件,例如缺少关键运行时参数,但即使如此,这也是值得怀疑的,因为系统不应该启动。

业务规则是什么?该字段允许为 null 吗?不是吗?

无论如何,在尝试对传入的任何参数进行操作之前检查它们是否为 null 始终是一个好习惯,这样当有人向您传递错误数据时,您就不会得到 NullPointerExceptions

You should never throw a runtime exception unless it is truly a fatal condition for the operation of the system, such as missing critical runtime parameters, but even then this is questionable as the system should just not start.

What are the business rules? Is null allowed for the field? Is it not?

In any case, it is always good practice to CHECK for nulls on ANY parameters passed in before you attempt to operate on them, so you don't get NullPointerExceptions when someone passes you bad data.

硬不硬你别怂 2024-10-27 13:12:51

如果您不知道是否应该这样做,那么很可能您不需要这样做。

JDK 源代码和 Joshua Bloch 的书是很糟糕的例子,因为它们针对的是非常不同的受众。我们中有多少人正在为数百万程序员编写公共 API?

If you don't know whether you should do it, the chances are, you don't need to do it.

JDK sources, and Joshua Bloch's book, are terrible examples to follow, because they are targeting very different audiences. How many of us are writing public APIs for millions of programmers?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文