Java 捕获空指针异常是一种代码味道吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2586290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:32:02  来源:igfitidea点击:

Is Catching a Null Pointer Exception a Code Smell?

javanullpointerexception

提问by Drew

Recently a co-worker of mine wrote in some code to catch a null pointer exception around an entire method, and return a single result. I pointed out how there could've been any number of reasons for the null pointer, so we changed it to a defensive check for the one result.

最近我的一个同事写了一些代码来捕获整个方法周围的空指针异常,并返回一个结果。我指出空指针可能有多种原因,因此我们将其更改为针对一个结果的防御性检查。

However, catching NullPointerException just seemed wrong to me. In my mind, Null pointer exceptions are the result of bad code and not to be an expected exception in the system.

然而,捕捉 NullPointerException 对我来说似乎是错误的。在我看来,空指针异常是错误代码的结果,而不是系统中的预期异常。

Are there any cases where it makes sense to catch a null pointer exception?

在任何情况下捕获空指针异常是否有意义?

采纳答案by Joachim Sauer

Yes, catching any RuntimeExceptionis almost always a code smell. The C2 Wikiseems to agree.

是的,捕获任何RuntimeException几乎总是一种代码气味。该C2维基似乎都同意。

An exception would probably be some specially defensive pieces of code which run pretty much random code from other modules. Examples for such defensive structures would be the EDT, ThreadPools/Executors and plugin system.

一个例外可能是一些特殊的防御性代码,它们运行来自其他模块的几乎随机代码。这种防御结构的例子是EDT、 ThreadPools/Executors 和插件系统。

回答by Michael Ekstrand

In general, I think it is a code smell; it seems to me that defensive checks are better. I would extend that to cover most unchecked exceptions, except in event loops, etc. that want to catch all errors for reporting/logging.

总的来说,我认为是代码异味;在我看来,防御性检查更好。我会扩展它以涵盖大多数未经检查的异常,除了在事件循环等中想要捕获所有错误以进行报告/记录。

The exception I can think of would be around a call to a library that can't be modified and which may generate a null pointer exception in response to some assertion failure that is difficult to proactively check.

我能想到的异常是对无法修改的库的调用,并且可能会生成空指针异常以响应某些难以主动检查的断言失败。

回答by OscarRyz

It depends.

这取决于。

How experienced this co-worker is? Is he doing this for ignorance/laziness or is there a real good reason for that? ( like this is the main thread above everything else and should never ever die? )

这位同事的经验如何?他这样做是因为无知/懒惰还是真的有充分的理由?(就像这是高于一切的主线程,永远不应该死?)

90% of the times catching a runtime exception is wrong, 99% catching a NullPointerException is wrong ( if the reason is "I was getting a lot of them..."then the whole programmer is wrong and you should look take care for the rest of the code he's doing )

90% 的时间捕获运行时异常是错误的,99% 捕获 NullPointerException 是错误的(如果原因是“我得到了很多......”那么整个程序员都是错误的,你应该注意他正在做的其余代码)

But under some circumstances catching a NullPointerException may be acceptable.

但在某些情况下,捕获 NullPointerException 可能是可以接受的。

回答by Tac-Tics

It certainly is.

那当然是。

Most of the time, your variables shouldn't be null to begin with. Many new languages are coming out with builtin support for non-nullable reference types -- that is, types which are guaranteed to never be null.

大多数情况下,您的变量一开始就不应该为空。许多新语言都带有对不可为空引用类型的内置支持——即保证永远不会为空的类型。

For the times when your incoming value is allowed to be null, you need to do a check. But exceptions are definitively a bad way to do this.

对于允许传入值为 null 的时间,您需要进行检查。但例外绝对是一种不好的方式来做到这一点。

An if statement takes perhaps three instructions to perform and is a local check (meaning, you make the check in the same place as you need the guarantee).

if 语句可能需要执行三个指令,并且是本地检查(意思是,您在需要保证的地方进行检查)。

Using an exception, on the other hand, may take many more instructions -- the system attempts to look up the method, fails, looks through the exception table for the appropriate exception handler, jumps there, executes the handler, and jumps again. Furthermore, the check is potentially non-local. If your code is something like this:

另一方面,使用异常可能需要更多的指令——系统尝试查找方法,失败,通过异常表查找适当的异常处理程序,跳转到那里,执行处理程序,然后再次跳转。此外,检查可能是非本地的。如果你的代码是这样的:

try
  return contacts.find("Mom").getEmail()
catch (NullPointerException e)
  return null

You don't know whether the NPE was thrown in 'getEmail' or in 'find'.

您不知道 NPE 是在“getEmail”还是“find”中抛出的。

A technical worse solution to a very, very common pattern written in a more obfuscated way? It isn't rank, but it definitely smells bad :/

以更模糊的方式编写的非常非常常见的模式的技术上更糟糕的解决方案?它不是排名,但它肯定闻起来很糟糕:/

回答by Tore

I try to guarantee results from my interfaces, but if some library or someones code can produce null as a result and im expecting a guarantee catching it might be viable. Ofcourse what you do once you catch it is up to you. Sometimes it just doesnt make sense to check for null, and if you catch it you have some other method of solving the problem that might not be as good but gets the job done.

我试图保证我的接口的结果,但是如果某些库或某人的代码可以产生 null 作为结果,我希望保证捕获它可能是可行的。当然,一旦你抓住它,你会做什么取决于你。有时检查 null 是没有意义的,如果你发现它,你有一些其他的方法来解决这个问题,这些方法可能不是那么好,但可以完成工作。

What im saying is use exceptions for what you can, its a pretty good language feature.

我说的是尽你所能使用异常,这是一个非常好的语言特性。

回答by Shervin Asgari

I have had to catch nullpointer exception sometimes because of a bug in third part library. The library we used threw that exception, and it was nothing we could do about it.

由于第三方库中的错误,我有时不得不捕获空指针异常。我们使用的库抛出了那个异常,我们对此无能为力。

In that case it is OKto catch it, otherwise not.

在这种情况下,它是OK抓住它,否则不是。

回答by GreenieMeanie

The only place you should catch a NullPointerException (or specifically, just any Throwable) is at some top-level or system boundary so that your program doesn't completely crash and can recover. For example, setting up an error page in your web.xml provides a catch-all so that a web application can recover from an exception and notify the user.

唯一应该捕获 NullPointerException(或者特别是任何 Throwable)的地方是在某个顶级或系统边界,这样您的程序就不会完全崩溃并且可以恢复。例如,在 web.xml 中设置错误页面提供了一个包罗万象的功能,以便 Web 应用程序可以从异常中恢复并通知用户。

回答by AV.

Catching a NullPointerException can be useful if your method calls an external interface (or a SOAP API) and there is a possibility that the value returned might be Null. Other than that, there is not a huge benefit to catching these exceptions.

如果您的方法调用外部接口(或 SOAP API)并且返回的值可能为 Null,则捕获 NullPointerException 会很有用。除此之外,捕捉这些异常并没有太大的好处。

回答by Stevko

It really depends on the interface definition. Unstructured NPE handling is as bad as catching Exception or Throwable.

这实际上取决于接口定义。非结构化 NPE 处理与捕获 Exception 或 Throwable 一样糟糕。

Nulls are useful for identifying an uninitialized state rather than using an empty string or max_int or whatever. Once place where I use null regularly is in places where a callback object is not relevant.

空值对于识别未初始化的状态很有用,而不是使用空字符串或 max_int 或其他任何东西。曾经我经常使用 null 的地方是回调对象不相关的地方。

I really like the @Nullable annotation provided by Guice.

我真的很喜欢 Guice 提供的 @Nullable 注释。

http://code.google.com/docreader/#p=google-guice&s=google-guice&t=UseNullable

http://code.google.com/docreader/#p=google-guice&s=google-guice&t=UseNullable

To eliminate NullPointerExceptions in your codebase, you must be disciplined about null references. We've been successful at this by following and enforcing a simple rule:

Every parameter is non-null unless explicitly specified. The Google Collections library and JSR-305 have simple APIs to get a nulls under control. Preconditions.checkNotNull can be used to fast-fail if a null reference is found, and @Nullable can be used to annotate a parameter that permits the null value.

Guice forbids null by default. It will refuse to inject null, failing with a ProvisionException instead. If null is permissible by your class, you can annotate the field or parameter with @Nullable. Guice recognizes any @Nullable annotation, like edu.umd.cs.findbugs.annotations.Nullable or javax.annotation.Nullable.

要消除代码库中的 NullPointerExceptions,您必须遵守空引用的纪律。通过遵循并强制执行一个简单的规则,我们在这方面取得了成功:

除非明确指定,否则每个参数都是非空的。Google Collections 库和 JSR-305 有简单的 API 来控制空值。如果找到空引用,Preconditions.checkNotNull 可用于快速失败,@Nullable 可用于注释允许空值的参数。

Guice 默认禁止 null。它将拒绝注入 null,而是以 ProvisionException 失败。如果您的类允许 null,您可以使用 @Nullable 注释字段或参数。Guice 识别任何 @Nullable 注释,如 edu.umd.cs.findbugs.annotations.Nullable 或 javax.annotation.Nullable。

回答by Jeffrey L Whitledge

I can think of exactly one use for ever catching a NullPointerException:

我可以想到捕捉一个的确切用途NullPointerException

catch (NullPointerException) {
    ApplyPainfulElectricShockToProgrammer();
}