Java 以安全的方式将字符串转换为整数

Java 以安全的方式将字符串转换为整数,java,type-conversion,Java,Type Conversion,我有一个小方法,它可以将字符串转换成整数。由于字符串是该方法的参数,因此我希望确保该字符串是可转换的。所以我只是想知道什么是最安全和/或最快的方法 版本A:保持现状,承担风险(我正试图避免) (在速度方面,它对版本B和C有什么不同?) 版本B:捕获异常 public static int stringToInt(String param) { try { return Integer.valueOf(param); } catc

我有一个小方法,它可以将字符串转换成整数。由于字符串是该方法的参数,因此我希望确保该字符串是可转换的。所以我只是想知道什么是最安全和/或最快的方法


版本A:保持现状,承担风险(我正试图避免)

(在速度方面,它对版本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应该是我的小程序中的“错误值”,换句话说,所有三个版本的方法在我的程序中都可以完美地工作

我非常乐意接受你能给我的任何其他建议,所以如果你认为你的更好,请随意创建你自己的版本


非常感谢您的支持。

首先,请注意,
C
版本不是防弹的:它将拒绝负数,并且不会捕获太大的数字

版本
B
是可以的,但它会使调用者更改编码样式:调用者不需要捕获错误并将其与其他错误一起处理,而需要始终检查
-1
。在读取多个整数的情况下,这可能是次优的,但错误处理并不取决于哪个整数失败。此外,使用API的新编码器可能忘记检查
-1
,并在无意中使用错误代码


这就是为什么我会选择第一个选项:使用版本
A
的代码对于任何了解Java API的人来说都会立即变得熟悉,而不需要了解函数内部发生了什么。

我相信修改后的B抛出异常而不是返回-1将是最佳选择。将异常抛出到可以处理的级别,以便向用户发送正确的响应,这样做很好。返回像-1这样的值会使代码容易出错。假设另一个程序员正在使用您的方法,并且他/她只拥有您方法的签名。因此,从签名中不清楚他/她应该编写什么代码来处理异常或错误场景。但是如果您抛出异常并将其添加到方法声明中,那么它将使其他程序员能够正确使用您的方法以及所需的异常处理。对我来说,这看起来是最好的:

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

Guava为此提供了一个实用方法,如果无法解析字符串,它将返回null


无任何API的Java 8:

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

使用replaceAll替换空白,即使看起来不需要,该加号也是cpu友好的。

如果错误不是正确的行为,并且如果您不想在更改的更高位置捕获
NumberFormatException
,则第一个版本只会有“风险”。抛出异常可能是对错误输入的完全健康的响应。在我看来,第一个异常是最快的,但如果您输入非数值,它将抛出异常。第二个对我来说是最好的,因为它有一个防止异常停止程序的捕获。最后一个,它只是第二个的一个长版本。C版本在负片上失败integers@bengoesboom我提到输入必须是正的EC正在检查A和B是否已经在内部执行。B是安全性和速度之间的一个很好的折衷。为什么要捕捉异常呢?OP指出,他们的实际方法做“其他事情”。它可能不那么方便地命名为
stringToInt
。显式声明抛出的异常可能是一个好主意,除非方法名称真的像
stringToInt
(当然还有上面提到的javadoc)一样清晰。如果数字以空格开头,我们就有错误:线程“main”java.lang.NumberFormatException中的异常:对于输入字符串:“1”注意:Ints.tryParse(String String)如果字符串为null,则将抛出NullPointerException。
Integer result = Ints.tryParse("1");  //returns 1
Integer result = Ints.tryParse("-1"); //returns -1
Integer result = Ints.tryParse("a");  //returns null
 Optional.ofNullable(strNum)
         .map(Integer::valueOf).orElse(null);
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);

*/

}