转换包含百分号的字符串时的JAVA:NumberFormat异常

时间:2015-01-19 11:39:33

标签: java

我正在使用第三方java jar文件将字符串转换为整数。

当字符串包含百分号“%”时,jar文件会抛出NumberFormatException。

以下是Jar文件的代码。

String str = "com%paq"; // this is the input string
//the jar file code starts here
byte[] b = new byte[1];
b[0] = (byte)(Integer.parseInt( str.substring( 2, 2 + 2 ), 16 ) & 0xFF);
s[j++] = (new String( b, 0, 1, "ASCII" )).charAt( 0 );

例外:

java.lang.NumberFormatException: For input string: "p%"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)

我无法更改jar文件代码。只要字符串中有“%”,就会执行上面的代码。

有没有办法避免异常?

5 个答案:

答案 0 :(得分:6)

该字符串没有数字,百分比字符只是问题的一部分。 str中没有要解析的数字(除非您尝试仅解析可被视为十六进制数字的字符 - ca - 您不这样做)。

您正在尝试解析包含字符p%p的子字符串%,这些字符不是十六进制数字。

如果要将输入字符串提供给jar,则可以通过在将输入传递给jar之前验证输入来验证相关字符是否为有效数字。你自己打电话给parseInt,如果你没有得到NumberFormatException,只将字符串传递给jar。

boolean isValid = true;
String str = "com%paq"; // this is the input string
try {
    int test = Integer.parseInt( str.substring( 2, 2 + 2 ), 16 );
}
catch (NumberFormatException ex) {
    isValid = false;
}
if (isValid) { // invoke the jar code
    //the jar file code starts here
    byte[] b = new byte[1];
    b[0] = (byte)(Integer.parseInt( str.substring( 2, 2 + 2 ), 16 ) & 0xFF);
    s[j++] = (new String( b, 0, 1, "ASCII" )).charAt( 0 );
}

答案 1 :(得分:1)

除了Erans的答案之外,我还想指出Integer的Java API文档,其中指出:

  

如果发生以下任何一种情况,则抛出NumberFormatException类型的异常:

     
      
  • 第一个参数为null或是一个长度为零的字符串。
  •   
  • 基数小于Character.MIN_RADIX或大于Character.MAX_RADIX。
  •   
  • 字符串的任何字符都不是指定基数的数字,除了第一个字符可能是减号' - ' (' \ u002D')或加号' +' (' \ u002B')前提是字符串长度超过1。
  •   
  • 字符串表示的值不是int类型的值。
  •   

您提供的第三方代码中的基数为16,因此它是十六进制的。这将允许传递的字符串的十进制数字0-9和字母A-F。

根据我的理解"com%paq"是一个字符串,您自己传递给第三方代码,并且在那里没有硬编码。所以你必须把它改成有效的东西。

答案 2 :(得分:0)

Integer.parseInt( str.substring( 2, 2 + 2 ), 16 )评估结果为"p%"

"p%"不是数字,这就是您的代码中出现NumberFormatException例外的原因

答案 3 :(得分:0)

Interger.parseInt(String str)仅转换包含" 123"," 675"等数字的字符串。等等。它不会将字符串转换为整数。如果要将字符串转换为整数,请使用String.hashCode();给出一个整数。

答案 4 :(得分:0)

我可以看到此代码正在尝试将字符串转换为十六进制数。正如您使用Integer.parseInt("String",radix)

很快我试图进行一些测试

  Integer.parseInt("e", 16) ;// prints 14 
  Integer.parseInt("f", 16) ;// prints 15
  Integer.parseInt("g", 16) ;// throws NumberFormat Exception 

基本就是这里,即使你想将十六进制字符转换为限制字符'a' ,'b' ... 'f'的数字,如果你的字符串包含除这些字母之外的字母,它肯定会失败NumberformatException。< / p>

正如您所看到的,String str = "com%paq"包含无效字母,如m,%,p,q。因此,即使使用substring (2,2+2),也会为m%提供无效的十六进制字符串。

有没有办法避免异常?

一种方法可以是首先验证输入字符串是否具有正确的字符,然后仅从jar调用该方法。

例如,假设整数转换逻辑存在于第三方jar中的getNumber()方法中,如下所示。 (用于演示目的的伪代码)

public byte[] getNumber(String str){
//the jar file code starts here
byte[] b = new byte[1];
b[0] = (byte)(Integer.parseInt( str.substring( 2, 2 + 2 ), 16 ) & 0xFF);
s[j++] = (new String( b, 0, 1, "ASCII" )).charAt( 0 );
.
.
.
  return b;
}

然后在调用getNumber

之前对字符串进行验证
if(str.matches("^[-+]?[0-9 a-f A-F]+")) //String validation logic .
{
    byte[] b = getNumber(str);
}

这样你可以避免异常。

  1. 如果未验证字符串,您可以在此处发送自定义消息

  2. 您还可以根据需要对字符串进行更多验证