2015-04-26 66 views
4

在Java中,我打這個電話:的Java Integer.valueOf產生NumberFormatException的爲有效號碼範圍內

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範圍內。

所以我的問題是,爲什麼會發生這種情況,我該如何解決?

N.B.正如你所看到的,我通過解析怪物獲得了chunkSizeAsString(「8d」),並懷疑可能存在隱形字符。我已經檢查了作爲使用以下添加上述線109中提到here「\ u200e」和「\ u200f」如前所述here,和「\\ p {Ç}」:

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

但這並沒有改變輸出。

編輯: 我使用jdk1.7.0_7,和供應商是 'Oracle公司'。謝謝fge

編輯2: 更新的JDK 1.7u79並意識到我需要從服務器獲取Java供應商那裏我運行和測試,不是我家的開發環境:

Java版本「1.7 .0_79"

OpenJDK的運行時環境(fedora的-2.5.5.0.fc20-x86_64的U79-B14)

OpenJDK的64位服務器VM(建立24.79-B02,混合模式)

編輯3: 以下的建議,我已經做了一些理智檢查:

  • 測試,檢查Integer.valueOf("8d", 16)Integer.parseInt("8d", 16)
  • chunkSizeAsString.equals("8d")是真
  • chunkSizeAsString.length() = 2個
  • 整數值的字符是56和100,它們分別是「8」和「d」的ASCII碼,全部分別爲
+3

哪個版本的Java(供應商,版本等)?另外,嘗試並轉儲字符串中的所有字符。 – fge

+0

我嘗試遍歷'chunkedSizeAsString'中的所有字符,引用每個字符(所以我會看到不可打印的字符)。只有'8'和'd'被發現。 – Tait

+0

您可以試用更新版本的JDK嗎? 7u7並不完全「新鮮」...... – fge

回答

3

試圖在一定的時間內對此進行調試,並且在給定更新和堆棧跟蹤(您在工作線程中的事實)後,我確信您在某種程度上會讓您嘗試使用多線程問題。

你的代碼改成這樣:

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能夠調試/解析究竟是什麼導致它而不被誤報情況拋出。

+0

@Tait @ durron597夥計們,請你詳細說明一下,究竟發生了什麼?異常'java.lang.NumberFormatException:對於輸入字符串:「8d」'被拋出 - 爲什麼?即使記住多線程,這怎麼可能? –

0

.valueOf使用.parseInt下,你可以做int chunkSize = Integer.parseInt(chunkSizeAsString, 16);

+0

我試過你的建議,沒有運氣。 – Tait

1

閱讀所有這些評論後,唯一有用的建議在這裏可以 - 只要調試它。不用擔心,按F7(或其他)並執行Integer.valueOf(),這很直接,你會立即看看出了什麼問題。

+0

我認爲這是一個很好的建議,即使它不是這種情況下的罪魁禍首。 – Tait