Java Integer.valueOf 为范围内的有效数字生成 NumberFormatException

标签 java string parsing integer

在 Java 中,我调用:

String chunkSizeAsString = responseString.split(DOUBLE_NEW_LINE)[1]
    .split(SINGLE_NEW_LINE)[0];
System.out.println("Trying to get integer value of '" + chunkSizeAsString + "'");
Integer chunkSize = Integer.valueOf(chunkSizeAsString, 16); // this is line 109

并得到输出:

Trying to get integer value of '8d'
Exception in thread "Thread-2" java.lang.NumberFormatException: For input string: "8d"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:481)
    at java.lang.Integer.valueOf(Integer.java:556)
    at ProxyWorker.handleRequest(ProxyWorker.java:109)
    at ProxyWorker.run(ProxyWorker.java:41)
    at java.lang.Thread.run(Thread.java:745)

基本上,我正在调用 Integer.valueOf("8d", 16) 并收到一个 NumberFormatException。我见过很多例子,其中 OP 忘记指定正确的基数,或者结果数字超出了 Integer、Long 等的范围。但是 0x8d = 141,这在 Integer 的范围内很舒服。

所以我的问题是,为什么会发生这种情况,我该如何解决?

注意如您所见,我正在通过一个异常的解析获取 chunkSizeAsString ("8d"),并且怀疑可能涉及不可见的字符。我已经检查了“\u200e”和“\u200f”,如前所述 here ,和提到的“\\p{C}”here在第 109 行上方使用以下添加:

chunkSizeAsString = chunkSizeAsString.replaceAll("\u200e", "");
chunkSizeAsString = chunkSizeAsString.replaceAll("\u200f", "");
chunkSizeAsString = chunkSizeAsString.replaceAll("[^\\p{Print}]", ""); 

但这并没有改变输出。

编辑: 我使用的是jdk1.7.0_7,供应商是'Oracle Corporation'。 谢谢fge .

编辑 2: 将 jdk 更新到 1.7u79 并意识到我需要从我正在运行和测试的服务器获取 java 供应商,而不是我的家庭开发环境:

java version "1.7.0_79"

OpenJDK Runtime Environment (fedora-2.5.5.0.fc20-x86_64 u79-b14)

OpenJDK 64-Bit Server VM (build 24.79-b02, mixed mode)

编辑 3: 按照建议,我做了一些完整性测试:

  • 检查 Integer.valueOf("8d", 16)Integer.parseInt("8d", 16) 的测试通过
  • chunkSizeAsString.equals("8d") 为真
  • chunkSizeAsString.length() = 2
  • 字符的整数值为56和100,分别是“8”和“d”的ASCII码

最佳答案

在尝试对此进行一定程度的调试后,考虑到您的更新和堆栈跟踪(事实上您在工作线程上),我相信您在某种程度上混淆了您的调试尝试与多线程问题.

将您的代码更改为:

private final AtomicInteger attemptCounter = new AtomicInteger(0);

void whateverYourMethodIsCalled(String responseString) {
    int attemptId = attemptCounter.incrementAndGet();
    System.out.format("Beginning attempt: %d%n", attemptId);
    String chunkSizeAsString = responseString.split(DOUBLE_NEW_LINE)[1]
        .split(SINGLE_NEW_LINE)[0];
    System.out.format("In attempt %d, trying to get integer value of '%s', which is length %d%n",
         attemptId, chunkSizeAsString, chunkSizeAsString.length());
    Integer chunkSize = Integer.valueOf(chunkSizeAsString, 16); // this is line 109
    System.out.format("Ending attempt: %d%n", attemptId);
}

最有可能发生的情况是,您第一次尝试正确工作,通过了调试用例,然后稍后处理的 String 引发了错误。


对评论的回应:似乎正在发生的事情是,最初的提问者正在处理大量数据和大量案例。在一个特定的案例中,他得到了隐形角色,但这不是问题发生的第一次,他混淆了这个问题和哪个特定案例引发了问题.通过隔离产生问题的解析数据,@Tait 能够准确地调试/解析导致问题的原因,而不会被误报情况所抛弃。

关于Java Integer.valueOf 为范围内的有效数字生成 NumberFormatException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29883882/

相关文章:

java - 监听jtable变化

c - 从 C 中的函数返回一个 const 字符串

java - 带有菜单图标的工具栏的默认高度

java - 在 Java Applet 中录制音频(策略文件选项)

java - 使用javamail api从地址获取?

c++ - 如何在 C++ 中从字符串中快速查找和子字符串化多个项目?

java替换字符串中的多个字符,包括 "\u00A2"

r - 函数输入参数中的交叉解析

python - 从字符串中提取带括号的 Python 表达式

java - 在 Java 中从 XML 获取子节点