Kon*_*lph 8 java defensive-programming exception
我来自.NET背景,现在涉足Java.
目前,我在设计防御输入错误的API方面遇到了大问题.假设我有以下代码(足够接近):
public void setTokens(Node node, int newTokens) {
tokens.put(node, newTokens);
}
Run Code Online (Sandbox Code Playgroud)
但是,此代码可能会失败有两个原因:
null节点.在.NET中,我会抛出一个ArgumentNullException(而不是一个NullReferenceException!)或ArgumentException分别传递有问题的参数(node)的名称作为string参数.
Java似乎没有等效的例外.我意识到我可以更具体,只是抛出最接近描述情况的异常,或者甚至为特定情况编写我自己的异常类.
这是最好的做法吗?或者是否存在类似于ArgumentException.NET 的通用类?
null在这种情况下检查是否有意义?无论如何代码都会失败,异常的堆栈跟踪将包含上面的方法调用.检查null似乎多余和过度.当然,堆栈跟踪会稍微清晰一些(因为它的目标是上面的方法,而不是HashMapJRE实现中的内部检查).但这必须抵消额外if声明的成本,此外,永远不应该发生 - 毕竟,传递null给上述方法不是预期的情况,这是一个相当愚蠢的错误.期待它是彻头彻尾的偏执 - 即使我不检查它也会失败,同样的例外.
[正如评论中指出的那样,HashMap.put实际上允许null键的值.所以这里的检查null不一定是多余的.]
小智 12
标准的Java异常是IllegalArgumentException.NullPointerException如果参数为null,有些人会抛出,但对我来说NPE有"有人搞砸"的含义,你不希望你的API的客户认为你不知道你在做什么.
对于公共API,请检查参数并尽早和干净地失败.时间/成本几乎不重要.
在Java中,您通常会抛出IllegalArgumentException
不同的群体有不同的标准.
首先,我假设您知道RuntimeExceptions(未检查)和正常Exceptions(已检查)之间的区别,如果没有,则查看此问题和答案.如果你写你自己的异常,你可以强制它被抓获,而这两个NullPointerException和IllegalArgumentException是它们在某些圈子里不赞成RuntimeExceptions.
其次,和你一样,我曾经合作但不主动使用断言的小组,但如果你的团队(或API的消费者)已经决定使用断言,那么断言就像正确的机制一样.
如果我是你,我会用NullPointerException.其原因是先例.从Sun获取示例Java API,例如java.util.TreeSet.这使用NPE来处理这种情况,虽然它看起来像你的代码只是使用了null,但这是完全合适的.
正如其他人所说的那样IllegalArgumentException是一种选择,但我认为NullPointerException更具沟通性.
如果这个API设计为外部公司/团队使用NullPointerException,我会坚持,但要确保它在javadoc中声明.如果它是供内部使用的话,你可能会认为添加你自己的Exception heirarchy是值得的,但我个人觉得那些添加了大量异常heirarchies的API只会printStackTrace()浪费精力.
在一天结束时,主要的是您的代码清晰地沟通.本地例外的heirarchy就像当地的行话一样 - 它为内部人员添加了信息,但可能会让局外人感到困惑.
关于检查null,我认为它确实有意义.首先,它允许您在构造有用的异常时添加有关null(即节点或标记)的消息.其次,将来您可能会使用Map允许的实现null,然后您将丢失错误检查.成本几乎为零,所以除非剖析器说这是一个内循环问题,否则我不担心.
| 归档时间: |
|
| 查看次数: |
5145 次 |
| 最近记录: |