Integer.parseInt不同jdk源码解析
执行以下代码:
System.out.println(Integer.parseInt("-123"));
System.out.println(Integer.parseInt("+123"));
以上提供1.6、1.7和1.8三个版本的比较
1.6版本执行结果为:

1.7版本执行结果为:

1.8版本执行结果为:

从两方面去查证结果的原因,分别是:查看API文档 和 查看对应的源代码
【查看API文档】
1.6版本对应的API文档:

1.7版本对应的API文档:

1.8版本对应的API文档:

可以看出,对第一个首字符,1.6只对 '-' 做了判定;1.7和1.8对 '-' 和 '+' 都做了判定。
【查看JDK源码】
1.6版本对应的源代码:
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
1.7版本对应的源代码:
char firstChar = s.charAt(0);
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
throw NumberFormatException.forInputString(s); if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
1.8的和1.7的源代码一样,这里就不冗余贴出来了。
对应jdk1.8源代码并做了相应的注解源码如下所示,帮助大家一起更加深入的理解:
public static int parseInt(String s, int radix) throws NumberFormatException {
/*
* WARNING: This method may be invoked early during VM initialization
* before IntegerCache is initialized. Care must be taken to not use
* the valueOf method.
*/
// 下面三个判断好理解,其中表示进制的 radix 要在(2~36)范围内
if (s == null) {
throw new NumberFormatException("null");
}
if (radix < Character.MIN_RADIX) {
throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
}
if (radix > Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
}
/**
* 表示结果, 在下面的计算中会一直是个负数
* 假如说 我们的字符串是一个正数 "7",那么在返回这个值之前result保存的是 -7
* 这个可能是为了保持正数和负数在下面计算的一致性
*/
int result = 0;
boolean negative = false;
int i = 0, len = s.length();
/**
* limit 默认初始化为 最大正整数的 负数 ,假如字符串表示的是正数
* 那么result(在返回之前一直是负数形式)就必须和这个最大正数的负数来比较,判断是否溢出
*/
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
if (len > 0) {
char firstChar = s.charAt(0); //首先是对第一个位置判断,是否含有正负号
if (firstChar < '0') { // Possible leading "+" or "-"
if (firstChar == '-') {
negative = true;
//这里在负号的情况下,判断溢出的值就变成了 整数的 最小负数了
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
throw NumberFormatException.forInputString(s);
if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
multmin = limit / radix;
/**
* len为输入字符串的长度,i为循环len自增变量
* result初始值为0,multmin初始值为最大负整数/进制数
*/
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
//根据Character类获取当前对应字符对应进制的数字
digit = Character.digit(s.charAt(i++),radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
/**
* 这里就是上面说的判断溢出,由于result统一用负值来计算,所以用了 小于 号
*/
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
/**
* 再来个假设:一开始输入一个数字字符串为123,那么对应的radix=10(因为是10进制的),digit = 123 / 10 计算得到的
* 第一次result *= radix --> result = 0 ; result -= digit --> result = -1
* 第二次result *= radix --> result = -10; result -= digit --> result = -12
* 第三次result *= radix --> result = -12; result -= digit --> result = -123
* 此时,negative = false,则返回 -result,即最终结果为:123
*/
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}
从以上源码可以看出,作者在计算整型数字的时候是采用取反的操作,即正数是通过负数进行计算,返回再取反操作。我猜想这样是为了在计算正负数的时候采取相同的策略,不需要为正数写一套方案,负数写一套方案,可以避免重复代码的嫌疑。
Integer.parseInt不同jdk源码解析的更多相关文章
- 设计模式-简单工厂Coding+jdk源码解析
感谢慕课geely老师的设计模式课程,本套设计模式的所有内容均以课程为参考. 前面的软件设计七大原则,目前只有理论这块,因为最近参与项目重构,暂时没有时间把Coding的代码按照设计思路一点点写出来. ...
- JDK源码解析之Java SPI机制
1. spi 是什么 SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件. 系统设计的各个抽象,往往 ...
- JDK源码解析---HashMap源码解析
HashMap简介 HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长. HashMap是非线程安全的,只是 ...
- JDK源码解析(一)ArrayList源码解析
这里为了方便写注释,我是把ArrayList的源码复制下来放到自己创建的类里面的 这个变量则指向具体存放数据的数组 看下构造函数吧 点进去看下LinkedList是怎么数组化的 很弱智吧,就是创建一个 ...
- 观察者模式JDK源码解析
由于JDK中为了方便开发人员,已经写好了现成的观察者接口和被观察者类. 先来观察者接口: //观察者接口,每一个观察者都必须实现这个接口 public interface Observer { //这 ...
- java JDK源码解析
Hashmap 使用java语言进行系统开发时,使用得比较多得数据结构hashmap,它以[key,value],进行数据存储,通过key可以快速找到到对应的value值,但是key,value不能是 ...
- JDK源码解析string之二
(28) public boolean startsWith(String prefix, int toffset) { char ta[] = value; int to = toffset; ch ...
- ArrayList源码解析,老哥,来一起复习一哈?
前言 JDK源码解析系列文章,都是基于JDK8分析的,虽然JDK14已经出来,但是JDK8我还不会,我... 类图 实现了RandomAccess接口,可以随机访问 实现了Cloneable接口,可以 ...
- 深入学习JDK源码系列之、ArrayList
前言 JDK源码解析系列文章,都是基于JDK8分析的,虽然JDK15马上要出来了,但是JDK8我还不会,我... 类图 实现了RandomAccess接口,可以随机访问 实现了Cloneable接口, ...
随机推荐
- Daily target小队介绍(刘畅,陈杰,杨有存,唐祎琳,王晓哲,邵汝佳)
一.团队介绍 1.团队构成: 2.队名: Daily target,我们的口号是Target your day! 3.团队项目描述: 我们计划写一个用于老师发布任务,学生接受任务的安卓app.教师安排 ...
- Week4-作业1:阅读与博客
第四章.两人合作 1.原文: 在变量面前加上有意义的前缀,程序员就能一眼看出变量的类型及相应的语义.这就是“匈牙利命名法”的用处.还有一些地方不适合用“匈牙利命名法”,比如,在一些强类型的语言(如C# ...
- 团队作业之404 Note Found Team
如果记忆是一个罐头的话,我希望这一罐罐头不会过期----<重庆森林> 404 Note Found Team 如果记忆是一个备忘录的话,别说了,它不会过期----<404 Note ...
- 转 webpack 插件 svg-sprite-loader
最近开始看 Vue 了,首先用官方的模版把项目快速搭建起来: Vue.js 提供一个官方命令行工具,可用于快速搭建大型单页应用.该工具提供开箱即用的构建工具配置,带来现代化的前端开发流程.只需几分钟即 ...
- 封装GetQueryString()方法来获取URL的value值(转载)
首先测试URL:http://192.168.1.82:8020/juzhong/daojishi.html?name=xiangruding&sex=nuuu&age=90 代码如下 ...
- Scrum 7.0
Sprint回顾 让我们一次比一次做得更好. 1.回顾组织 主题:“我们怎样才能在下个sprint中做的更好?” 时间:设定为1至2个小时. 参与者:整个团队. 场所:能够在不受干扰的情况下讨论. ...
- 软工网络15团队作业8——Beta阶段敏捷冲刺(Day4)
提供当天站立式会议照片一张 每个人的工作 1.讨论项目每个成员的昨天进展 赵铭: 在知晓云上建立数据表 吴慧婷:做了背单词界面并学习了词库界面的设计. 陈敏: 我的词库-全部词汇功能/新建词汇功能全部 ...
- IPV6的链路本地地址和站点本地地址的不同
转帖 中关村 http://ask.zol.com.cn/x/2230274.html IPV6涉及到一个概念,link-local address, 中文叫“链路本地地址”,它的前缀是FE80::/ ...
- 微信公众平台实现获取用户OpenID的方法
这篇文章主要介绍了微信公众平台实现获取用户OpenID的方法,需要开发人员经过微信授权后获取高级接口才能使用此功能,用户OpenID对于微信公众平台建设有着非常广泛的用途,需要的朋友可以参考下 本文实 ...
- linux 进程guanl管理的常用几个命令
执行中的程序在称作进程.当程序以可执行文件存放在存储中,并且运行的时候,每个进程会被动态得分配系统资源.内存.安全属性和与之相关的状态.可以有多个进程关联到同一个程序,并同时执行不会互相干扰.操作系统 ...