安全地将字符串转换为整数

17

我有一个小方法,其中包括将字符串转换为整数的功能。由于该字符串是该方法的参数,我想确保该字符串可转换。所以我想知道最安全和/或最快的方法。


版本A:让它保持原样并冒风险(这正是我试图避免的)

public static int stringToInt(String param) {
        return Integer.valueOf(param);
}

(就速度而言,版本B和C会有什么不同?)


版本B: 捕获异常

public static int stringToInt(String param) {
        try {
                return Integer.valueOf(param);
        } catch(NumberFormatException e) {
                return -1;
        }
}

版本 C:检查字符串中的每个字母,判断它是否为数字。

public static int stringToInt(String param) {
        for(char c : param.toCharArray()) {
                if(!Character.isDigit(c))
                        return -1;
        }
        return Integer.valueOf(param);
}
请注意,参数必须是正数,-1 应该是我小程序中的“错误值”,换句话说,三个版本的方法在我的程序中都能完美地工作。如果您认为您的方法更好,请随意创建您自己的版本,我非常乐意接受任何其他建议。非常感谢您提前的支持。

2
如果错误不是正确的行为,而且您不想在更高层次上捕获NumberFormatException,则第一个版本只会存在“风险”。抛出异常可以是对错误输入的完全健康的响应。 - Louis Wasserman
版本C在负整数上失败。 - bengoesboom
@bengoesboom 我提到输入必须是正数。 - felix fritz
2
C正在执行A和B已经在内部执行的检查。B是安全性和速度之间的良好折衷方案。 - Stephen Carlson
@Craig 我完全同意 - bengoesboom
显示剩余5条评论
6个回答

12

3
注意:如果字符串为null,Ints.tryParse(String string)将抛出NullPointerException异常。 - Donald

7
首先需要注意的是,版本C不是万无一失的:它会拒绝负数,并且无法捕获过大的数字。
版本B可以,但它要求调用者改变编码风格:而不是捕获错误并将其与其他错误一起处理,调用者需要一直检查-1。在读取多个整数但错误处理不依赖于哪一个失败的情况下,这可能不是最佳选择。此外,使用您的API的新程序员可能会忘记检查-1,并无意中使用错误代码。
这就是为什么我建议继续使用第一种选项:A版本的代码对于熟悉Java API的任何人来说都是瞬间熟悉的,而不需要了解函数内部发生了什么。

OP指出他们的实际方法执行了“其他操作”。 它可能没有像stringToInt这样方便的名称。 明确声明抛出的异常很可能是个好主意,除非方法名称确实像stringToInt一样清晰(当然还要有相应的javadoc)。 - Gus

3
我认为修改B方法,使其抛出异常而不是返回-1将是最好的选择。将异常抛出到合适的层级进行处理并向用户发送正确的响应是一个好的做法。返回像-1这样的值会使你的代码容易出错。假设另一个程序员正在调用你的方法,他/她只有你的方法签名。所以从签名中无法清楚地知道他/她应该编写什么来处理异常或错误情况。但是如果你抛出异常并将其添加到方法声明中,则可以使其他程序员正确使用你的方法,并进行必要的异常处理。对我来说,这看起来是最好的:
public static int stringToInt(String param) throws NumberFormatException {
        try {
                return Integer.valueOf(param);
        } catch(NumberFormatException e) {
               // return -1;
               throw e;
        }
}

12
为什么要捕获异常? - Craig

1

没有任何API的Java 8:

 Optional.ofNullable(strNum)
         .map(Integer::valueOf).orElse(null);

2
如果数字以空格开头,我们会遇到错误:Exception in thread "main" java.lang.NumberFormatException: For input string: " 1" - Topera

1
public int stringToInt(String param) throws NumberFormatException {

    Optional.ofNullable(param.replaceAll("\\s+", ""))
         .map(Integer::valueOf).orElse(null);

/*
                      or

    Optional.ofNullable(param.replaceAll(" ", ""))
         .map(Integer::valueOf).orElse(null);

*/

}

使用replaceAll替换空格,加号对CPU友好,即使看起来似乎不需要。

0

我结合了两个答案来处理 nulls、空字符串、空格以及非数字字符:

public static Integer safeStringToInt(String param) {
    return Optional.ofNullable(param).map(Ints::tryParse).orElse(null);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接