And*_*lov 84 java parsing exception
相当愚蠢的问题.鉴于代码:
public static int sum(String a, String b) /* throws? WHAT? */ {
int x = Integer.parseInt(a); // throws NumberFormatException
int y = Integer.parseInt(b); // throws NumberFormatException
return x + y;
}
Run Code Online (Sandbox Code Playgroud)
你能告诉它是不是很好的Java?我所说的是,NumberFormatException是一个未经检查的例外.您不必将其指定为sum()签名的一部分.此外,据我所知,未经检查的异常的想法只是表示程序的实现是不正确的,甚至更多,捕获未经检查的异常是一个坏主意,因为它就像在运行时修复坏程序.
请有人澄清是否:
NumberFormatException为方法签名的一部分.BadDataException),NumberFormatException在方法内部处理并重新抛出它BadDataException.BadDataException),像正则表达式一样验证两个字符串,BadDataException如果它不匹配则抛出我的字符串.更新:
想象一下,它不是一个开源框架,你应该出于某种原因使用它.你看看方法的签名并思考 - "好吧,它永远不会抛出".然后,有一天,你有一个例外.这是正常的吗?
更新2:
有一些评论说我sum(String, String)的设计不好.我绝对同意,但对于那些认为如果我们有好的设计就不会出现原始问题的人来说,这是一个额外的问题:
问题定义如下:您有一个数据源,其中数字存储为Strings.这个源可能是XML文件,网页,带有2个编辑框的桌面窗口,等等.
你的目标是实现采用这些2 String秒的逻辑,将它们转换为ints并显示消息框,说"总和是xxx".
无论您使用什么方法来设计/实现它,您都将拥有以下2点内部功能:
String为的地方intint秒的地方我原帖的主要问题是:
Integer.parseInt()期望传递正确的字符串.每当你传递一个错误的字符串,就意味着你的程序不正确(而不是" 你的用户是个白痴").你需要实现这段代码,其中一方面你有Integer.parseInt()和MUST语义,另一方面你需要在输入不正确的情况下做好 - 应该是语义.
简而言之:如果我只有MUST库,我该如何实现SHOULD语义.
Joh*_*erg 49
在我看来,最好尽可能地处理异常逻辑.因此我更喜欢签名
public static int sum(int a, int b);
Run Code Online (Sandbox Code Playgroud)
使用您的方法签名,我不会改变任何东西.不管你是谁
因此,在这种情况下,异常处理成为文档问题.
Boh*_*ian 35
这是一个很好的问题.我希望更多的人会考虑这些事情.
如果你已经通过垃圾参数,恕我直言,抛出未经检查的例外是可以接受的.
一般来说,您不应该抛出,BadDataException因为您不应该使用Exceptions来控制程序流.例外是特殊情况.你的方法的调用者可以在他们调用之前知道他们的字符串是否为数字,因此传递垃圾是可以避免的,因此可以被认为是编程错误,这意味着可以抛出未经检查的异常.
关于声明throws NumberFormatException- 这没有那么有用,因为很少会注意到由于未选中NumberFormatException.但是,IDE可以使用它并提供try/catch正确的包装.一个很好的选择是使用javadoc,例如:
/**
* Adds two string numbers
* @param a
* @param b
* @return
* @throws NumberFormatException if either of a or b is not an integer
*/
public static int sum(String a, String b) throws NumberFormatException {
int x = Integer.parseInt(a);
int y = Integer.parseInt(b);
return x + y;
}
Run Code Online (Sandbox Code Playgroud)
编辑:
评论者提出了有效的观点.您需要考虑如何使用它以及应用程序的整体设计.
如果该方法将在所有地方使用,并且所有调用者处理问题都很重要,则将该方法声明为抛出已检查的异常(强制调用者处理问题),但是使用try/catch块使代码混乱.
另一方面,如果我们将这个方法与我们信任的数据一起使用,那么就像上面那样声明它,因为它不会爆炸并且你避免了基本上不必要的try/catch块的代码混乱.
数字4.如上所述,此方法不应将字符串作为应采用整数的参数.在这种情况下(因为java包装而不是溢出),不存在异常的可能性.
x = sum(Integer.parseInt(a), Integer.parseInt(b))
Run Code Online (Sandbox Code Playgroud)
比什么意思要清楚得多
x = sum(a, b)
您希望异常尽可能接近源(输入).
对于选项1-3,您没有定义异常,因为您希望您的调用者假设您的代码不会失败,您定义一个异常来定义在已知的失败条件下发生的事情,这对您的方法来说是独一无二的.即如果你有一个方法是另一个对象的包装器,它会抛出一个异常,然后传递它.只有当异常对你的方法是唯一的时候才应该抛出一个自定义异常(在你的例子中,如果sum应该只返回正结果,那么检查它并抛出异常将是合适的,如果另一方面java抛出溢出异常而不是包装,然后你会传递它,而不是在你的签名中定义它,重命名它,或者吃掉它).
更新以回应问题的更新:
简而言之:如果我只有MUST库,我该如何实现SHOULD语义.
解决方法是包装MUST库,并返回SHOULD值.在这种情况下,返回一个Integer的函数.编写一个接受字符串并返回Integer对象的函数 - 它可以工作,或者返回null(比如guava的Ints.tryParse).您的验证是否与您的操作分开,您的操作应该采取整合.当您输入无效时,是否使用默认值调用操作,或者您执行其他操作时,将取决于您的规范 - 我可以说最多的是,是否真的不可能做出该决定的地方在操作中方法.