探讨 Java 中 valueOf 和 parseInt 的区别
文章目录
- 前言
- 区别
- parseInt
- valueOf
- 后记
前言
在编程中,遇到类型转换,好像会经常用到 parseInt
和 valueOf
,当然这里只拿 Integer
类型进行陈述,其他类型也是雷同的;
想必有读者也跟我一样,经常交叉使用这两个方法,但却不知道这两者到底有什么区别,接下来就来探究一番;
区别
Integer.parseInt(s)
的作用就是把字符串 s 解析成有符号基本类型的 int;Integer.valueOf(s)
把字符串 s 解析成 Integer 对象类型,返回的对象可以调用 Integer 中的方法;
接下来,通过源码进行逐一解析;
parseInt
我们首先点进 parseInt()
方法中,
public static int parseInt(String s) throws NumberFormatException {return parseInt(s, 10);
}
可以看到,这个被我们调用的 parseInt()
方法返回了一个重载方法:
public static int parseInt(String s, int radix) throws NumberFormatException {if (s == null) {throw new NumberFormatException("null");} else if (radix < 2) {throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");} else if (radix > 36) {throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");} else {boolean negative = false;int i = 0;int len = s.length();int limit = -2147483647;if (len <= 0) {throw NumberFormatException.forInputString(s);} else {char firstChar = s.charAt(0);if (firstChar < '0') {if (firstChar == '-') {negative = true;limit = -2147483648;} else if (firstChar != '+') {throw NumberFormatException.forInputString(s);}if (len == 1) {throw NumberFormatException.forInputString(s);}++i;}int multmin = limit / radix;int result;int digit;for(result = 0; i < len; result -= digit) {digit = Character.digit(s.charAt(i++), radix);if (digit < 0 || result < multmin) {throw NumberFormatException.forInputString(s);}result *= radix;if (result < limit + digit) {throw NumberFormatException.forInputString(s);}}return negative ? result : -result;}}
}
1、首先看到的是,该方法传入了两个参数,parseInt(String s, int radix)
,这个可以根据被调用时传入的参数,return parseInt(s, 10);
,盲猜一下,s
就是表示要转换成数字型的字符串,而 radix
英文是基数的意思,这里应该表示进制,即这个传入的字符串是多少进制的,那到底是不是呢,我们接着往下看;
2、这里先是对字符串 s
是否为空,以及 radix
的大小进行一个判断,不符合条件则抛出 NumberFormatException
异常,也就是数字格式化异常;
if (s == null){throw new NumberFormatException("null");
} else if (radix < 2) {throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
} else if (radix > 36) {throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
} else {
3、接着往下,再一次对长度进行一个校验,
int len = s.length();
if (len <= 0) {throw NumberFormatException.forInputString(s);
} else {...
}
我在这里只想到了一个能让它抛出异常的条件,
Integer.parseInt("");
运行结果:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)at java.base/java.lang.Integer.parseInt(Integer.java:662)at java.base/java.lang.Integer.parseInt(Integer.java:770)
4、接下来会检测第一个字符是啥,如果是 -
,则将 negative
设置成 true
,表示这是个负数,并且将边界 limit
设置成最小边界;
如果不是 +
,则表示该字符既不是数字,不也是性质符号,因此抛出 NumberFormatException
异常;
如果字符串 s
的长度只有1,则表明这是非数字,不符合要求,也抛出 NumberFormatException
异常;
++i
是因为如果第一位是符号的话,那么在后续的循环中追加数字则直接跳过首位;
char firstChar = s.charAt(0);if (firstChar < '0') {if (firstChar == '-') {negative = true;limit = -2147483648;} else if (firstChar != '+') {throw NumberFormatException.forInputString(s);}if (len == 1) {throw NumberFormatException.forInputString(s);}++i;}
5、根据进制来调整边界,以防越界;
int multmin = limit / radix;
6、Character.digit()
用于将字符转为为对应进制的整数,如果该字符不是进制内的就返回-1,例如输入的字符是9,但是进制是2,那么就不符合,则会返回-1;
然后就是进行计算;
int result;
int digit;
for(result = 0; i < len; result -= digit) {digit = Character.digit(s.charAt(i++), radix);if (digit < 0 || result < multmin) {throw NumberFormatException.forInputString(s);}result *= radix;if (result < limit + digit) {throw NumberFormatException.forInputString(s);}
}
7、最后判断是否为负数完成转换;
return negative ? result : -result;
valueOf
照例查看源码:
public static Integer valueOf(String s, int radix) throws NumberFormatException {return parseInt(s, radix);
}public static Integer valueOf(String s) throws NumberFormatException {return parseInt(s, 10);
}@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {return i >= -128 && i <= Integer.IntegerCache.high ? Integer.IntegerCache.cache[i + 128] : new Integer(i);
}
可以看出 valueOf(String s, int radix)
和 valueOf(String s)
都是直接调用返回了 parseInt
方法,而 valueOf(int i)
则是一个 int
转成 Integer
的自动装箱;
接下来探究一下 IntegerCache
,可以看出这是 Integer
的成员内部类,来看源码:
private static class IntegerCache {static final int low = -128;static final int high;static final Integer[] cache;static Integer[] archivedCache;private IntegerCache() {}static {int h = 127;String integerCacheHighPropValue = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");int size;if (integerCacheHighPropValue != null) {try {size = Integer.parseInt(integerCacheHighPropValue);size = Math.max(size, 127);h = Math.min(size, 2147483518);} catch (NumberFormatException var6) {}}high = h;VM.initializeFromArchive(Integer.IntegerCache.class);size = high - -128 + 1;if (archivedCache == null || size > archivedCache.length) {Integer[] c = new Integer[size];int j = -128;for(int k = 0; k < c.length; ++k) {c[k] = new Integer(j++);}archivedCache = c;}cache = archivedCache;assert high >= 127;}
}
整体就是初始化一个 IntegerCache.cache
数组,数组里面存储-128到127之间的数字当做是缓存,源码一开始是分析数组长度,然后给数组赋值;
总的来说,三个重构的 valueOf()
方法还是大同小异的:
Integer valueOf(int i)
:返回一个表示指定的 int 值的 Integer 实例;Integer valueOf(String s)
:返回保存指定的 String 的值的 Integer 对象;Integer valueOf(String s, int radix)
:返回一个 Integer 对象,该对象中保存了用第二个参数提供的基数进行解析时从指定的 String 中提取的值;
后记
看源码还是能学到很多东西的,源码自有黄金屋,多看多学,夯实基础,之后会轻松高效很多!
探讨 Java 中 valueOf 和 parseInt 的区别相关推荐
- java中Runnable和Callable的区别
文章目录 运行机制 返回值的不同 Exception处理 java中Runnable和Callable的区别 在java的多线程开发中Runnable一直以来都是多线程的核心,而Callable是ja ...
- Java中valueOf()方法
Java中valueOf()方法 1.先看源代码怎么说: Returns an Integer object holding the value of the specified String,The ...
- JAVA中int 是什么意思,java中int和Integer什么区别
java中int和Integer的区别 一看就懂 int 是基本类型,直接存数值 integer是对象,用一个引用指向这个对象 1.Java 中的数据类型分为基本数据类型和复杂数据类型 int 是前 ...
- java中的异常种类和区别以及处理机制和区别
java中的异常种类和区别以及处理机制和区别 按照异常需要处理的时机分为编译时异常(也叫强制性异常)也叫 CheckedException 和运行时异常(也叫非强制性异常)也叫 RuntimeExce ...
- java中ArrayList和LinkedList的区别
首先来看ArrayList和LinkedList的集成类和接口的区别.// lang java public class ArrayList<E> extends AbstractList ...
- java中wait和sleep的区别
文章目录 Wait和sleep的区别 唤醒wait和sleep java中wait和sleep的区别 在本篇文章中,我们将会讨论一下java中wait()和sleep()方法的区别.并讨论一下怎么使用 ...
- java throw与throws_基于Java中throw和throws的区别(详解)
系统自动抛出的异常 所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,并且 Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行. 语句抛出的异常 ...
- Java中重载和复写的区别
Java中重载和复写的区别 重载(overload) 复写(override) 区别和联系 重载(overload) 函数重载的最突出的例子就是类的构造函数,用户定义一个对象时可能会提供多种参数组合: ...
- Java中equals()方法和==的区别分析
Java中equals方法和==的区别分析 equals(Object obj)方法,将对象与传入的obj进行比较,相等返回true,否则返回false.equals方法和"==" ...
最新文章
- [云炬python3玩转机器学习]4-7机器学习算法训练和测试样本集数据同时归一化
- 经典SQL语句大全(技巧篇)
- IC设计常见设计思想
- Vue自定义指令-实时时间转换指令 v-time开发
- ibatis 模糊查询 mysql_Mybatis使用MySQL模糊查询时输入中文检索不到结果怎么办
- 基于消息的异步套接字
- DM8168 DDR3接口的PCB布线指南
- java实现基于关键字的文件夹(文件)的搜索、文件夹(文件)的复制、删除
- Android package属性、package name和Application ID三者的联系及区别
- 易语言卷帘菜单与json_易语言卷帘式菜单加背景图片源码
- PEP 635 – Structural Pattern Matching: Motivation and Rationale
- 预测web服务的未来
- 在list中筛选出符合条件的数据(返回list)
- UIImageView视图内容按比例缩小并淅淅隐去
- 利用python爬取京东平台评论及图片并进行分析
- ubuntu ..路径找不到_Ubuntu常用命令
- 实现将网页多条磁力链接一次性全部下载
- boost asio 文件服务器,基于boost::asio封装搭建的简单服务器
- 我不常用的Linux命令
- 编译原理 期末考试复习题
热门文章
- VMware里Windows7安装VMware Tools失败?跑去安装补丁也碰壁?看这一篇就够了
- 电商平台学习笔记(五)——空指针异常--NullPointException
- Pycham无法创建py文件的问题
- python爬虫学习DAY1_Requests库
- 嵌套select语句
- 《iBoard 是什么》之简介
- 网络/Network - 网络编程 - 高性能 - 单服务器高性能模式[网络模型]及性能对比 - 学习/实践
- iperf测试网络带宽
- Android设备网络数据流量统计
- python坐标轴位置_Python Matplotlib 改变坐标轴的默认位置