预期时处理数字formatexception的正确方法是什么?
-
08-10-2019 - |
题
我遇到了我需要解析的情况 String
进入 int
而且我不知道该怎么办 NumberFormatException
. 。当我不抓住它时,编译器不会抱怨,但我只想确保我正在正确处理这种情况。
private int getCurrentPieceAsInt() {
int i = 0;
try {
i = Integer.parseInt(this.getCurrentPiece());
} catch (NumberFormatException e) {
i = 0;
}
return i;
}
我只想简化我的代码。编译器没有问题,但是线程在 NumberFormatException
.
private int getCurrentPieceAsInt() {
int i = 0;
i = Integer.parseInt(this.getCurrentPiece());
return i;
}
Google Codepro希望我以某种方式记录例外,我同意这是最佳实践。
private int getCurrentPieceAsInt() {
int i = 0;
try {
i = Integer.parseInt(this.getCurrentPiece());
} catch (NumberFormatException e) {
i = 0;
e.printStackTrace();
}
return i;
}
我希望这种方法返回 0
当目前的作品不是数字或无法解析时。当我不抓住 NumberFormatException
明确地,它不分配变量 i
?还是有一些默认值 Integer.parseInt()
返回?
通用风格说,如果我发现异常,我应该在某个地方记录下来。我不想记录它。有时会抛出这个例外是正常的操作,这对我来说也不是很好。但是,我找不到功能,这会告诉我是否 Integer.parseInt()
会抛出例外。因此,我唯一的行动似乎只是称呼它并抓住例外。
这 Javadoc 为了 parseInt
无济于事。
这是我想知道的具体问题:
- 有没有我可以称呼的方法可以告诉我是否
Integer.parseInt()
会扔一个NumberFormatException
在打电话之前?然后,我不会有任何问题,因为它永远不会发生。 - 如果我根本不捕获异常,会不会分配阀门?然后,我将简单地将其初始化为我想要的值,而不是一个数字而不会捕获异常。
- 有没有办法明确地标记我不在乎的例外?我认为这会类似
AWTEvent.consume()
. 。如果是这样,那么我将这样做,以便Google Codepro不会将其视为“ Unlogged”。
解决方案
- 我可以调用一种方法可以告诉我Integer.parseint()在调用它之前会抛出numberFormateXception吗?然后,我不会有任何问题,因为它永远不会发生。
可悲的是没有。至少不在核心Java API中。但是,写一个很容易 - 只需修改以下代码即可。
- 如果我根本不捕获异常,会不会分配阀门?然后,我将简单地将其初始化为我想要的值,而不是一个数字而不会捕获异常。
如果您不捕获异常,那么堆栈将放松,直到它撞到可以处理它的捕获块,否则它将完全放松并停止线程。实际上,该变量不会被分配,但这并不是您想要的。
- 有没有办法明确地标记我不在乎的例外?我认为这将类似于Awtevent.consume()。如果是这样,那么我将这样做,以便Google Codepro不会将其视为“ Unlogged”。
可能有一种方法告诉Codepro忽略此特定警告。当然,使用Findbugs和CheckStyle之类的工具,您可以在特定位置关闭警告。 (编辑:@andy指出了如何做到这一点。)
我怀疑您想要的是@DaveB提到的Commons Lang软件包。写这样的功能很容易:
int parseWithDefault(String s, int def) {
try {
return Integer.parseInt(s);
}
catch (NumberFormatException e) {
// It's OK to ignore "e" here because returning a default value is the documented behaviour on invalid input.
return def;
}
}
其他提示
有 numberutils.toint(字符串,int) 在 下议院朗 这将完全做您想要的。
NumberUtils.toInt("123", 42) ==> 123
NumberUtils.toInt("abc", 42) ==> 42
* Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".
是的,您可以在本地禁用一行代码的CodePro审核规则:
http://code.google.com/javadevtools/codepro/doc/features/audit/locally_disabling_audit_rules.html
也就是说,不一定需要在每个例外捕获块中包括诊断记录。有时,最好的动作是参加默认课程。有时是与用户互动。这取决于。
现在和将来创建自己的便利方法:
public static int parseInt(final /*@Nullable*/ String s, final int valueIfInvalid) {
try {
if (s == null) {
return valueIfInvalid;
} else {
return Integer.parseInt(s);
}
} catch (final NumberFormatException ex) {
return valueIfInvalid;
}
}
我可以调用一种方法可以告诉我Integer.parseint()在调用它之前会抛出numberFormateXception吗?然后,我不会有任何问题,因为它永远不会发生。
并不是我知道。请记住,如果有的话,您最终可能会两次解析该值(一次验证并一次解析)。我了解您想避免例外,但是在这种情况下,这是Java中的标准成语,它没有提供另一个习语(至少我知道)。
如果我根本不捕获异常,会不会分配阀门?然后,我将简单地将其初始化为我想要的值,而不是一个数字而不会捕获异常。
您必须捕获例外(即使它什么也不做),否则它将逃脱块并通过堆栈扔掉。
有没有办法明确地标记我不在乎的例外?我认为这将类似于Awtevent.consume()。如果是这样,那么我将这样做,以便Google Codepro不会将其视为“ Unlogged”。
我不知道。我将使用上述便利方法(我在所有项目中都可以使用的一小部分通用公用事业中有类似的东西)。
如果您确实要处理的是正常情况,我不会记录它。我不喜欢Google Codepro,但我希望有一种方法可以抑制警告,例如某种@suppresswarnings(“ xxx”)注释/关键字。
编辑: 我想在下面的评论中指出这些评论
这种方法仍然无法处理异常。遇到例外并无能为力是不好的。这就是为什么我正在寻找更好的解决方案
.
...例外(情况) 正在处理 通过返回指定的valiefinvalid。这 “不良形式” 你指的是 盲目和不思想地写空的捕获块的不良练习 而且永远不要真正考虑并解决此案。如果是 考虑了例外情况,并做正确的事 对于情况(即使正确的事情是什么都不做), 然后 您已经“处理”了例外.
您应该像这样做时捕获例外。这很烦人,但是最好的方法。
当字符串不是有效的int时,没有Java API方法将返回0。
当字符串不是int时,将会引发异常,因此,除非您像这样做一样捕获异常,否则不会设置您的int变量。
如果您不清楚如何从Getter中处理它,则不应抓住它,而是让呼叫者处理它。如果您知道应该如何处理它,则应该做到这一点。在这种情况下,记录它可能不需要或非常有用。
如果您不知道如何处理异常,而将其留给阅读日志的人,则记录异常会更有用。
您的第一个代码块是正确的。 i
当发生异常时,不会隐式转换为0,您必须捕获该异常。环境 i
到0内 catch
是正确的;虽然您可以简单地替换 i = 0;
和 return 0;
. 。在这种情况下,您无法避免例外处理。
为了澄清,您可以使用以下方式:
private int getCurrentPieceAsInt() {
int i = 0;
try {
i = Integer.parseInt(this.getCurrentPiece());
} catch (NumberFormatException e) {
// log that an exception occured if it's needed
return 0;
}
return i;
}
正如其他人提到的那样,您可以调用内置核心Java API方法来验证整数,但是您可以使用该方法 Character
验证您的输入的课程 没有 使用异常处理。例如:
package com.example.parseint;
public class ValidateIntExample {
public static boolean isInteger(String s) {
if (s == null) {
return false;
}
s = s.trim();
if (s.length() == 0) {
return false;
}
int start = 0;
if (s.charAt(0) == '-') { // handle negative numbers
if (s.length() == 1) {
return false;
}
else {
start = 1;
}
}
for (int i = start; i < s.length(); i++) {
if (! Character.isDigit(s.charAt(i))) {
return false;
}
}
return true;
}
}
实际上, parseInt
本身使用 Character.isDigit
内部,您可以在JRE源代码中验证。 (对不起,我会包括 parseInt
这里的方法,但我不确定是否允许我按照许可条款进行。)如果您使用的是Eclipse并且已随附了项目的JRE源代码,则可以右键单击该方法 Integer.parseInt
在您的代码中,然后单击“打开声明”。