先说最终解决方案:try + parseLong() 即可,下面记录一下这个坑的踩坑经历:
踩坑经历
前一阵子在写后端业务逻辑的时候遇到了String转Long的需求,一开始用的Long.parseLong,这样在转空字符串、带小数数字字符串或者其他非数字字符串的时候就会报一个异常:java.lang.NumberFormatException: For input string: "5L"
于是便修改成了Long.getLong方法,简单测试了一下,发现Long.getLong方法空字符串,非数字字符串都返回的null,不会报错,这不完美了了吗?那Entity转Dto的时候那些字段就省掉好多try catch语句了。
但是我偏偏忘了测试最重要的,正确的数字字符串也不能转换了,返回的也是null,测试如下:
System.out.println(Long.getLong("7")); // null
System.out.println(Long.getLong("2")); // null
System.out.println(Long.getLong("3L")); // null
System.out.println(Long.getLong("-1L")); // null
System.out.println(Long.getLong("1L")); // null
System.out.println(Long.getLong("java.lang.Long")); // null所以说,有时候真的不能太想当然(捂脸)
见招拆招,那干脆以Long为例,把那些字符串转数字的所有方法整理一下,省的下次遇到又走一遍老路。
new Long("7"): 构造函数传值,内部调用了parseLong()方法
Long.parseLong: 返回的是 long 基本类型(注意大小写),非数字字符串/带小数数字字符串会报NumberFormatException。
Long.valueOf: 返回的是 Long 对象,内部调用了parseLong()方法,仅仅是包装成了 Long 对象。
Long.decode: 返回的是 Long 对象,可以解析以0x、0X、#、0开头的字符串,分别表示这个字符串是16或8进制的数字字符串,而parseLong、valueOf只能解析纯数字的10进制字符串。内部调用了valueOf()方法。
Long.parseUnsignedLong: 返回的是 long 基本类型(注意大小写),字面意思,只是转无符号数字,带符号会报错java.lang.NumberFormatException: Illegal leading minus sign on unsigned string -1.,内部调用了parseLong()方法。
你看其实这些函数内部都是调用的 parseLong()/parseUnsignedLong(),其他的只是包装了一层而已,所以说,咱们还是老老实实的用 parseLong 方法+try catch捕获异常吧。
顺便说一句,其他的几个类型也是类似,大家就记住字符串转数字用 parseXxx 就行:
// 整数类型
Byte.parseByte("1");
Short.parseShort("1");
Integer.parseInt("1");
Long.parseLong("1");
// 小数类型
Float.parseFloat("1.0");
Double.parseDouble("1.0");解决方法 & 封装工具类
可能我这个工具类写的也比较粗略,肯定有比我这样写更优雅的方式,比如可以直接引入第三方依赖比如hutool(https://www.hutool.cn/)这一类。人家有封装好的常用函数,不需要自己完成,这样封装确实能满足我的业务需求。但是,我觉得自己封装一个Util工具类其实就够了,为了这一个小问题引入一个依赖,我觉得没太大必要,大家可以根据自己项目实际情况自行决定。
public class NumberParseUtils {
/**
* Long 转 String 工具类
* <p>
* 非数字类型字符串getLong之后为null,不会报错
*
* @param str
* @return 转换失败时不报错,返回 null
*/
public static Long parseLong(String str) {
return parseLong(str, null);
}
/**
* Long 转 String 工具类
* <p>
* 非数字类型字符串getLong之后为null,不会报错
*
* @param str
* @return 转换失败时不报错,返回 defaultValue
*/
public static Long parseLong(String str, Long defaultValue) {
if (str == null) {
return defaultValue;
}
try {
return Long.parseLong(str);
} catch (NumberFormatException e) {
return defaultValue;
}
}
}测试用例
测试用例如下:
import com.example.backend.common.Utils.NumberParseUtils;
public class NumberParseUtilsTest {
public static void main(String[] args) {
System.out.println("new Long");
System.out.println(new Long("7"));
System.out.println("Long.getLong");
System.out.println(Long.getLong("7")); // null
System.out.println(Long.getLong("2")); // null
System.out.println(Long.getLong("3L")); // null
System.out.println(Long.getLong("-1L")); // null
System.out.println(Long.getLong("1L")); // null
System.out.println(Long.getLong("java.lang.Long")); // null
// long
System.out.println("Long.parseLong");
System.out.println(Long.parseLong("-1")); // -1
System.out.println(Long.parseLong("3")); // 3
// System.out.println(Long.parseLong("5L"));
// Exception in thread "main" java.lang.NumberFormatException: For input string: "5L"
// Long
System.out.println("Long.valueOf");
System.out.println(Long.valueOf("-1")); // -1
System.out.println(Long.valueOf("3")); // 3
// System.out.println(Long.valueOf("5L"));
// Exception in thread "main" java.lang.NumberFormatException: For input string: "5L"
System.out.println(Long.valueOf("011")); // 输出11
// System.out.println(Long.valueOf("#11")); // 出错
// System.out.println(Long.valueOf("0X11"));// 出错
// System.out.println(Long.valueOf("0x11"));// 出错
System.out.println(Long.valueOf("11")); // 输出11
System.out.println("Long.decode");
System.out.println(Long.decode("-1")); // -1
System.out.println(Long.decode("3")); // 3
// System.out.println(Long.decode("5L"));
// Exception in thread "main" java.lang.NumberFormatException: For input string: "5L"
System.out.println(Long.decode("011")); // 8进制,输出9
System.out.println(Long.decode("#11")); // 16进制,输出17
System.out.println(Long.decode("0X11"));// 16进制,输出17
System.out.println(Long.decode("0x11"));// 16进制,输出17
System.out.println(Long.decode("11")); // 10进制,输出11
System.out.println("Long.parseUnsignedLong");
// System.out.println(Long.parseUnsignedLong("-1"));
// Exception in thread "main" java.lang.NumberFormatException: Illegal leading minus sign on unsigned string -1.
System.out.println(Long.parseUnsignedLong("3")); // 3
// System.out.println(Long.parseUnsignedLong("5L"));
// Exception in thread "main" java.lang.NumberFormatException: For input string: "5L"
System.out.println("NumberParseUtils.parseLong");
System.out.println(NumberParseUtils.parseLong("1"));
System.out.println(NumberParseUtils.parseLong(""));
System.out.println(NumberParseUtils.parseLong("0"));
System.out.println(NumberParseUtils.parseLong("3487215432148412423")); // 19位,可以正常解析
System.out.println(NumberParseUtils.parseLong("34872154321484124234")); // 20位,返回null
// 为小数值时,String类型不能转为Long类型
System.out.println(NumberParseUtils.parseLong("0.5"));
System.out.println(NumberParseUtils.parseLong("-3.2L"));
System.out.println(NumberParseUtils.parseLong("abc"));
System.out.println(NumberParseUtils.parseLong(null));
}
}张小弟之家原创,转载请标注原作者及本页链接
本站文章除注明转载/出处外,均为原创,若要转载请务必注明出处。转载后请将转载链接通过邮件告知我站,谢谢合作。本站邮箱:admin@only4.work
尊重他人劳动成果,共创和谐网络环境。点击版权声明查看本站相关条款。
GitHub登录