1:首先我们可以通过一个main函数,通过断点调试,正式开启Integer.toString()方法之旅。
public static void main ( String[] arg ) {

System.out.println( Integer.toString( 65537 ) );

}
2: 首先我们会看到进入toString(int i)的方法之内
public static String toString(int i) {

    if (i == Integer.MIN_VALUE) (1)return "-2147483648";int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); (2)char[] buf = new char[size]; (3)getChars(i, size, buf); (4)return new String(buf, true); (5)
}

从(1)中我们就可以看到 判断是否为整数的最小的数,是的话,直接返回"-2147483648"字符串,在(2)中这里通过 stringSize(-i) 判断是否为小数 二进制中,小数的第一位是符号位,负数等于所比正数多了一位,在(3)中新创建了一个char[]数组,我们通过研究string的源码可知,String的本质就是一个char[]数组,对String的操作,就是操作char[]里面的每一个对象,为了搞清楚(4)与(5)的作用,首先,我们先进入stringSize(i)的方法里面都看看做了什么。

3: 高效的位数计算方法 stringSize(i);

final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,

                                  99999999, 999999999, Integer.MAX_VALUE };
static int stringSize(int x) {for (int i=0; ; i++) (1)if (x <= sizeTable[i]) (2)return i+1;
}

从(1)中可知,首先进入一个无限for循环中,但是由于sizeTable参数的限制,其实最多可以循环10此,例如我们,断点调试时传入的值是65537,那么它就会循环5次,得到是一个5位的数字,那么就返回4。char[] buf = new char[4],
正好就可以创建一个正好放下65537的数组。

4: 功能强大的getChars(i, size, buf);

static void getChars(int i, int index, char[] buf) {

    int q, r;int charPos = index;char sign = 0;if (i < 0) {      (1)sign = '-';i = -i;}while (i >= 65536) {  (2)q = i / 100;r = i - ((q << 6) + (q << 5) + (q << 2)); (3)i = q;buf [--charPos] = DigitOnes[r];  (4)buf [--charPos] = DigitTens[r];  (5)}for (;;) { (6)q = (i * 52429) >>> (16+3);  (7)r = i - ((q << 3) + (q << 1));  (8)buf [--charPos] = digits [r];  (9)i = q;if (i == 0) break;}if (sign != 0) {buf [--charPos] = sign;  (10)}
}从(1)处可知,我们知道负数的第一位是“-”号,并且负数比正数多了一位,除了“-”号位之外,所有的内容和正数完全相同,紧接着,会进入(2)的一个循环语句,为什么是65536呢,我们知道65536正好等于2的16次方,二正数的最大值是2的32次方减1,可以说,65536是正数的最大值的一半,大于65536的位高位数,小于65536的是低位数,65537/100正好是655,((q << 6) + (q << 5) + (q << 2))这一段的作用等于 (q * 100),通过位运算与加法运算,避免乘除运算以提高效率。紧接着r=37进入(4)和(5)的数组,(4)和(5)的数组设计简直称为神奇。final static char [] DigitTens = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0','1', '1', '1', '1', '1', '1', '1', '1', '1', '1','2', '2', '2', '2', '2', '2', '2', '2', '2', '2','3', '3', '3', '3', '3', '3', '3', '3', '3', '3','4', '4', '4', '4', '4', '4', '4', '4', '4', '4','5', '5', '5', '5', '5', '5', '5', '5', '5', '5','6', '6', '6', '6', '6', '6', '6', '6', '6', '6','7', '7', '7', '7', '7', '7', '7', '7', '7', '7','8', '8', '8', '8', '8', '8', '8', '8', '8', '8','9', '9', '9', '9', '9', '9', '9', '9', '9', '9',} ;final static char [] DigitOnes = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9','0', '1', '2', '3', '4', '5', '6', '7', '8', '9',} ;通过这两个数组,正好得到buf [4]=7,buf [3]=3的值。接下来,就会进入(6)为代表的for无限循环中(其实有限的,这样写感觉好精炼),(7)的作用相当于除以10,右移16+3也就是右移19位,也就是除以2的19次方,2的19次方=524288 ,而52429除以524288为0.1000003814697266的精度已经很多了,就几乎等于0.1,而52429/524288得到的数字精度在不超出整形范围内,精度是最高的。(8)r = i - ((q << 3) + (q << 1))相当于r = i-(q*10),也是为了提高运算效率。类似的通过(9)与(10)即可得到字符数组 char[] ={"6","5","5","3","7"}至此,最后调用new String(buf, true)方法,返回想要的字符串

JDK 源码 Integer解读之一(toString)相关推荐

  1. java int类源码,一起学JDK源码 -- Integer类

    Integer类为java基本类型int的包装类,除了前面提到的Byte类,Short类中的大部分方法,Integer类中还提供了很多处理int类型的方法,接下来就让我们一起看看吧. 基础知识: 1. ...

  2. JDK源码学习笔记——Integer

    一.类定义 public final class Integer extends Number implements Comparable<Integer> 二.属性 private fi ...

  3. JDK源码解析 Integer类使用了享元模式

    JDK源码解析 Integer类使用了享元模式. 我们先看下面的例子: public class Demo {public static void main(String[] args) {Integ ...

  4. 从JDK源码角度看Long

    概况 Java的Long类主要的作用就是对基本类型long进行封装,提供了一些处理long类型的方法,比如long到String类型的转换方法或String类型到long类型的转换方法,当然也包含与其 ...

  5. JDK源码解析 Comparator 中的策略模式

    JDK源码解析 Comparator 中的策略模式.在Arrays类中有一个 sort() 方法,如下: public class Arrays{public static <T> voi ...

  6. JDK源码学习笔记——String

    1.学习jdk源码,从以下几个方面入手: 类定义(继承,实现接口等) 全局变量 方法 内部类 2.hashCode private int hash; public int hashCode() {i ...

  7. 从JDK源码角度看Short

    概况 Java的Short类主要的作用就是对基本类型short进行封装,提供了一些处理short类型的方法,比如short到String类型的转换方法或String类型到short类型的转换方法,当然 ...

  8. 为什么jdk源码推荐ThreadLocal使用static

    ThreadLocal是线程私有变量,本身是解决多线程环境线程安全,可以说单线程实际上没必要使用. 既然多线程环境本身不使用static,那么又怎么会线程不安全.所以这个问题本身并不是问题,只是有人没 ...

  9. JDK源码研究Jstack,JMap,threaddump,dumpheap的原理

    JDK最新bug和任务领取:https://bugs.openjdk.java.net/projects/JDK/issues 参加OpenJDK社区:https://bugs.openjdk.jav ...

最新文章

  1. Linux下命令行ssh密钥连接服务器
  2. 【KVM系列07】使用 libvirt 做 QEMU/KVM 快照和 Nova 实例的快照
  3. 指令打印与驱动打印随笔
  4. Ubuntu在vmware虚拟机无法上网的解决方法
  5. spring mvc学习(51):jsonp
  6. 智慧交通day02-车流量检测实现04:卡尔曼滤波器
  7. Oracle 安装时候的fs.aio-max-nr参数
  8. html5 页面答题算分,JavaScript实现答题评分功能页面
  9. Java编程实现获取本机IP和计算机名的功能
  10. Spring源码分析-Bean生命周期概述
  11. WEX5导出excel
  12. 易语言MYSQL记账工具_易语言做记账软件
  13. fetch bulk collect limt 学习
  14. window 10 安装node.js时遇到2502 2503错误解决方法
  15. 零基础入门UI设计必备实用技巧!
  16. 在Mac os上使用LaTex
  17. Mysql 数据库——Mysql 数据库管理
  18. foot元素内容未满或超过一页都底部显示
  19. FBI树--字符二叉树
  20. TIO-websoket-showcase 学习笔记

热门文章

  1. 揭秘:一个月不摸鱼能写多少代码?
  2. 漫画 | 程序员必须要小心的 7 个潜规则
  3. HSRP多组基础配置实验
  4. squid一些其它配置
  5. 构建工具Gradle
  6. 【机器学习】--隐含马尔科夫模型从初识到应用
  7. java日记(2)------定时任务quartz浅析
  8. 【Cocos2d-x】开发实战-Cocos中的字符串、标签和中文乱码
  9. HDU 1285--确定比赛名次【拓扑排序 amp;amp; 邻接表实现】
  10. ZooKeeper集群安装