繁体   English   中英

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

[英]JAVA : NumberFormat exception when converting a string containing percent sign

我正在使用将字符串转换为整数的第三方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文件代码。 只要字符串中有“%”,上述代码就会始终执行。

有什么办法可以避免这种异常?

该字符串没有数字,百分比字符只是问题的一部分。 没有数解析str (除非您尝试来解析可以被视为十六进制数字字符- ca -你没有)。

您正在尝试分析子字符串p% ,其中包含字符p% ,它们不是十六进制数字。

如果将输入字符串提供给jar,则可以在将输入传递给jar之前验证输入,以验证相关字符是否为有效数字。 您自己调用parseInt ,并且仅在未获取NumberFormatException才将String传递给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 );
}

除了Erans答案之外,我还要向您介绍Integer的Java API文档,该文档指出:

如果发生以下任一情况,将引发NumberFormatException类型的异常:

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

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

据我了解, "com%paq"是您自己传递给第三方代码的字符串,并且未在其中进行硬编码。 因此,您必须将其更改为有效值。

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

"p%"不是数字,这就是代码中出现NumberFormatException异常的原因

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

我可以看到该代码正在尝试将字符串转换为十六进制数字。 如您所使用的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失败。

如您所见, String str = "com%paq"包含无效的字母,例如m,%,p,q。 因此,即使使用substring (2,2+2)也会给您m% ,后者仍然是无效的十六进制字符串。

有什么办法可以避免这种异常?

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

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

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. 如果未验证String,则可以在此处发送自定义消息

  2. 您还可以根据要求对String进行更多验证

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM