【问题标题】:How to detect overflow when convert string to integer in java在java中将字符串转换为整数时如何检测溢出
【发布时间】:2012-02-26 06:23:44
【问题描述】:

如果我想在 java 中将字符串转换为 int 你知道我是否有办法检测溢出吗? 我的意思是字符串文字实际上代表一个大于 MAX_INT 的值?

java 文档没有提到它.. 它只是说如果字符串不能被解析为整数,它将通过 FormatException 一个字都没提溢出。。

【问题讨论】:

  • @darkmist 谢谢。知道它会引发异常会有所帮助。我仍然知道什么样的异常等等......你能给我指出描述行为的文档吗?
  • NumberFormatExceptionparseInt 声明为public static int parseInt(String s, int radix) throws NumberFormatException)。顺便说一句,docs.oracle.com/javase/1.4.2/docs/api/java/lang/Integer.html 中有一个样本太长,不适合 int
  • @darkmist 如果发生以下任何一种情况,则会引发 NumberFormatException 类型的异常:(不包含太大的值...)第一个参数为 null 或长度为零的字符串。基数小于 Character.MIN_RADIX 或大于 Character.MAX_RADIX。字符串的任何字符都不是指定基数的数字,除非第一个字符可以是减号'-'('\u002D'),前提是字符串的长度大于1。字符串表示的值是不是 int 类型的值。
  • @darkmist 另外 String.intValue 的行为如何?

标签: java


【解决方案1】:

如果我想在java中将一个字符串转换为一个int,你知道我是否有办法检测溢出吗?

是的。捕获解析异常将是正确的方法,但这里的困难在于Integer.parseInt(String s) 会为 any 解析错误引发NumberFormatException,包括溢出。您可以通过查看 JDK 的 src.zip 文件中的 Java 源代码来验证。幸运的是,存在一个构造函数 BigInteger(String s) 将抛出相同的解析异常,except 用于范围限制异常,因为 BigIntegers 没有边界。我们可以利用这些知识来捕获溢出情况:

/**
 * Provides the same functionality as Integer.parseInt(String s), but throws
 * a custom exception for out-of-range inputs.
 */
int parseIntWithOverflow(String s) throws Exception {
    int result = 0;
    try {
        result = Integer.parseInt(s);
    } catch (Exception e) {
        try {
            new BigInteger(s);
        } catch (Exception e1) {
            throw e; // re-throw, this was a formatting problem
        }
        // We're here iff s represents a valid integer that's outside
        // of java.lang.Integer range. Consider using custom exception type.
        throw new NumberFormatException("Input is outside of Integer range!");
    }
    // the input parsed no problem
    return result;
}

如果您确实需要为超过 Integer.MAX_VALUE 的输入自定义此设置,您可以在抛出自定义异常之前使用@Sergej 的建议进行此操作。如果上面是矫枉过正并且您不需要隔离溢出情况,只需通过捕获它来抑制异常:

int result = 0;
try {
    result = Integer.parseInt(s);
} catch (NumberFormatException e) {
    // act accordingly
}

【讨论】:

  • 捕捉和投掷Exception 是不好的做法。
  • @Stephen 听起来很有趣。有什么解释或参考吗?
  • @paislee 谢谢。我想我只想问 NFE 是否检测到溢出,因为 java doc 没有提到它。但知道如何隔离病例也有帮助。然而令我惊讶的是,源代码(不是某种标准)是获取信息的最终手段......
【解决方案2】:

将字符串值转换为 Long 并将 Long 值与 Integer.Max_value 进行比较

    String bigStrVal="3147483647";        
    Long val=Long.parseLong(bigStrVal);
    if (val>Integer.MAX_VALUE){
        System.out.println("String value > Integer.Max_Value");
    }else
        System.out.println("String value < Integer.Max_Value");

【讨论】:

  • @yangsuli 把它包在一个函数里,你就不用再看它了。恕我直言,这非常优雅.. 除了 Long 也有一个 MAX_VALUE,所以它仍然不能保证解析。
  • @paislee Long.Max_Value 究竟为什么它不是一个解决方案...在这里捕获异常对我来说似乎更优雅(当然,如果 Java 允许我这样做...)
  • 恐怕这比没有更糟糕,因为它给人的印象是在做这项工作,但不是因为没有处理溢出的数字。
【解决方案3】:

你不需要做任何事情。

正如Integer.parseInt(str, radix)Javadoc 状态,如果字符串表示的值不能表示为int 值,则会抛出NumberFormatException;即如果它的幅度太大。这被描述为与str 格式错误的情况不同的情况,因此(对我而言)很清楚这就是意思。 (您可以通过阅读源代码来确认这一点。)

【讨论】:

  • 它可能被描述作为一个单独的案例,但实际上没有直接的方法来区分这些案例。该方法在6种情况下抛出异常,它们都是相同的异常。请参阅src 代码。
  • 但是 OP 询问了 检测 溢出,而不是 区分 它与其他问题。 NFE 确实检测到溢出,我认为这才是 OP 真正关心的问题。
猜你喜欢
  • 2019-01-05
  • 1970-01-01
  • 2015-08-07
  • 2013-02-05
  • 2016-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多