当需要时处理 NumberFormatException 的正确方法是什么?

发布于 2024-10-07 04:36:37 字数 1715 浏览 6 评论 0原文

我遇到了这种情况,我需要将 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 for parseInt 没有多大帮助。

以下是我想知道的具体问题:

  • 是否有一个我可以调用的方法可以告诉我在调用之前 Integer.parseInt() 是否会抛出 NumberFormatException它?那么我记录这个就没有问题了,因为它永远不会发生。
  • 如果我只是不捕获异常,valable 不会被分配吗?然后,当它不是数字时,我将简单地将其初始化为我想要的值,并且不捕获异常。
  • 有没有办法以某种方式明确标记异常,表明我不关心它?我认为这与 AWTEvent.consume() 类似。如果是这样,那么我将这样做,以便 Google CodePro 不会将其视为“未记录”。

I'm running into this situation where I need to parse a String into an int and I don't know what to do with the NumberFormatException. The compiler doesn't complain when I don't catch it, but I just want to make sure that I'm handling this situation properly.

private int getCurrentPieceAsInt() {
    int i = 0;
    try {
        i = Integer.parseInt(this.getCurrentPiece());
    } catch (NumberFormatException e) {
        i = 0;
    }
    return i;
}

I want to just simplify my code like this. The compiler doesn't have a problem with it, but the thread dies on the NumberFormatException.

private int getCurrentPieceAsInt() {
    int i = 0;
    i = Integer.parseInt(this.getCurrentPiece());
    return i;
}

Google CodePro wants me to log the exception in some way, and I agree that this is best practice.

private int getCurrentPieceAsInt() {
    int i = 0;
    try {
        i = Integer.parseInt(this.getCurrentPiece());
    } catch (NumberFormatException e) {
        i = 0;
        e.printStackTrace();
    }
    return i;
}

I want this method to return 0 when the current piece is not a number or cannot be parsed. When I don't catch the NumberFormatException explicitly, does it not assign the variable i? Or is there some default value that Integer.parseInt() returns?

General style says that if I catch an exception, I should log it somewhere. I don't want to log it. It's normal operation for this exception to be thrown sometimes, which also doesn't sit well with me. I cannot find a function, however, which will tell me if Integer.parseInt() will throw an exception. So my only course of action seems to be to just call it and catch the exception.

The javadoc for parseInt doesn't help much.

Here are the specific questions I'd like to know:

  • Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.
  • If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.
  • 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".

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

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

发布评论

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

评论(8

雨巷深深 2024-10-14 04:36:37
  • 我可以调用一个方法来告诉我 Integer.parseInt() 在调用它之前是否会抛出 NumberFormatException 吗?那么我记录这个就没有问题了,因为它永远不会发生。

遗憾的是,没有。至少在核心 Java API 中不是这样。然而,编写一个很容易 - 只需修改下面的代码即可。

  • 如果我只是不捕获异常,valable 不会被分配吗?然后,当它不是数字时,我将简单地将其初始化为我想要的值,并且不捕获异常。

如果您没有捕获异常,那么堆栈将展开,直到遇到将处理该异常的 catch 块,否则它将完全展开并停止线程。事实上,该变量不会被分配,但这并不完全是您想要的。

  • 有没有办法以某种方式明确标记异常,表明我不关心它?我认为这与 AWTEvent.consume() 类似。如果是这样,那么我将这样做,以便 Google CodePro 不会将其视为“未记录”。

可能有一种方法可以告诉 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;
    }
}
  • Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.

Sadly, no. At least not in the core Java API. It's easy to write one, however - just modify the code below.

  • If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.

If you do not catch the exception then the stack will unwind until it hits a catch block that will handle it, or it will unwind completely and halt the thread. The variable will, in fact, not be assigned but this is not exactly what you want.

  • 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".

There may be a way to tell CodePro to ignore this particular warning. Certainly with tools like FindBugs and Checkstyle you can turn off warnings in specific locations. (EDIT: @Andy has pointed out how to do this.)

I suspect what you want is something like the Commons lang package mentioned by @daveb. It's pretty easy to write such a function:

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;
    }
}
听,心雨的声音 2024-10-14 04:36:37

NumberUtils.toInt(String, int) in commons lang 其中会做你想做的事。

NumberUtils.toInt("123", 42) ==> 123
NumberUtils.toInt("abc", 42) ==> 42

There is NumberUtils.toInt(String, int) in commons lang which will do exactly what you want.

NumberUtils.toInt("123", 42) ==> 123
NumberUtils.toInt("abc", 42) ==> 42
短叹 2024-10-14 04:36:37
* 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

也就是说,不一定需要在每个异常捕获块中包含诊断日志记录。有时,最好的行动是采取默认路线。有时是与用户交互。这取决于。

* 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".

Yes, you can locally disable a CodePro audit rule for one line of code:

http://code.google.com/javadevtools/codepro/doc/features/audit/locally_disabling_audit_rules.html

That said, it is not necessarily required to include diagnostic logging in every exception catch block. Sometimes, the best action is to take a default course. Sometime it's to interact with the user. It depends.

蓝天 2024-10-14 04:36:37

创建您自己的方便方法以供现在和将来使用:

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 中的标准习惯用法,并且它没有提供另一个(至少我知道)。

如果我只是不捕获异常,valiable 是否不会被分配?然后,当它不是数字时,我会将其初始化为我想要的值,并且不会捕获异常。

您必须捕获异常(即使它什么都不做),否则它将逃逸块并通过堆栈抛出。

有没有办法以某种方式明确标记异常,表明我不关心它?我认为这与 AWTEvent.consume() 类似。如果是这样,那么我将这样做,以便 Google CodePro 不会将此视为“未记录”。

我什么都不知道。我会使用上面的便捷方法(我在一小部分通用实用程序中有类似的东西,可用于我的所有项目)。

如果这确实是您正在处理的正常情况,我不会记录它。我不熟悉 Google CodePro,但我希望有一种方法可以抑制警告,例如某种 @SuppressWarnings("xxx") 注释/关键字。


编辑:我想在下面的评论中指出这些评论

这种方法仍然不能处理异常。捕获异常而不对其进行任何操作是不好的形式。这就是为什么我正在寻找更好的解决方案

...异常(情况)正在通过返回指示的 valueIfInvalid 进行处理。您所指的“坏形式”是指盲目地、不假思索地编写空的catch块的不良做法并且永远不会回去真正考虑和解决案件。如果考虑了异常情况并针对该情况采取了正确的做法即使正确的做法是什么都不做),那么您就已经“处理”了例外

Create your own convenience method for now and future use:

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;
    }
}

Is there a method that I can call that will tell me if Integer.parseInt() will throw a NumberFormatException before calling it? Then I would have no problem logging this, since it should never happen.

Not that I'm aware of. Keep in mind that if there were, you likely end up parsing the value twice (once to validate and once to parse it). I understand you want to avoid the exception, but in this case, this is catching the exception is the standard idiom in Java and it doesn't provide another (at least that I know of).

If I simply do not catch the exception, will the valiable not get assigned? Then I will simply initialize it to the value that I want when it's not a number and not catch the exception.

You must catch the exception (even if it does nothing) or it will escape the block and throw up through the stack.

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".

I don't know of any. I would use the above convenience method (I have something similar in a small collection of general utilities I have available for use on my all projects).

I wouldn't log it if its truly a normal condition that you are handling. I'm not familiiar with Google CodePro, but I would hope there is a way to suppress the warning, e.g. some sort of @SuppressWarnings("xxx") annotation/keyword.


Edit: I wanted to point out these comments in the comments below

This approach still doesn't handle the exception. It's bad form to catch an exception and do nothing with it. This is why I am looking for a better solution

.

... The exception (the situation) is being handled by returning the indicated valueIfInvalid. The "bad form" you are referring to the poor practice of blindly and unthinkingly writing empty catch blocks and never going back to truly consider and address the case. If the exception situation is considered and does the right thing for the situation (even if the right thing is to do nothing), then you've "handled" the exception.

偏爱自由 2024-10-14 04:36:37

您应该在执行时捕获异常。这很烦人,但却是最好的方法。

当字符串不是有效的 int 时,没有任何 Java API 方法会返回 0。

当字符串不是 int 时,将引发异常,因此除非您捕获异常,否则不会设置 int 变量。

You should catch the Exception as you are doing. It is annoying, but the best approach.

There is no Java API method that will return 0 when the string is not a valid int.

When the string is not an int, an exception will be thrown so your int variable will not be set unless you catch the exception as you are doing.

尴尬癌患者 2024-10-14 04:36:37

如果不清楚如何从 getter 中处理它,则不应捕获它并让调用者处理它。如果您知道应该如何处理它,您就应该这样做。在这种情况下,记录它可能不是必需的或非常有用。

如果您不知道如何处理异常并将其留给阅读日志的人,则记录异常会更有用。

If its not clear how you should handle it from the getter, you shouldn't catch it and let the caller deal with it instead. If you know how it should be handled you should just do that. Logging it may not be required or very useful in this case.

Logging an exception is more useful if you don't know how to handle the exception and you are leaving it to the person reading the logs.

海夕 2024-10-14 04:36:37

您的第一个代码块是正确的。当发生异常并且您必须捕获该异常时,i 不会隐式转换为 0。在catch中将i设置为0是正确的;尽管您可以简单地将 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;
}

Your first code block is correct. i won't be implicitly converted to 0 when an exception occurs and you have to catch that exception. Setting i to 0 inside catch is correct; although you can simply replace i = 0; with return 0;. You cannot avoid exception handling in this case.

To clarify, you can use this:

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;
}
暮凉 2024-10-14 04:36:37

正如其他人提到的,没有可以调用的内置核心 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,然后单击“打开声明”。

As others have mentioned, there is not a built-in core Java API method you can call to validate an integer, but you can use the Character class to validate your input without using exception handling. For example:

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;
    }
}

In fact, parseInt itself uses Character.isDigit internally, which you can verify in the JRE source code. (Sorry, I would have included the parseInt method here, but I'm not sure if I'm allowed under the license terms.) If you're using Eclipse and you have the JRE source code attached to your project, you can right-click on the method Integer.parseInt in your code and click Open Declaration.

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