一、类定义

public final class Integer extends Number implements Comparable<Integer>

二、属性

    private final int value;// fianl
private static final long serialVersionUID = 1360826667806852920L;
// 值为 (-(2的31次方)) 的常量,它表示 int 类型能够表示的最小值。
public static final int MIN_VALUE = 0x80000000;
// 值为 ((2的31次方)-1) 的常量,它表示 int 类型能够表示的最大值。
public static final int MAX_VALUE = 0x7fffffff;
// 表示基本类型 int 的 Class 实例。
public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
// 用来以二进制补码形式表示 int 值的比特位数。
public static final int SIZE = 32;
// 用来以二进制补码形式表示 int 值的字节数。1.8以后才有
public static final int BYTES = SIZE / Byte.SIZE;
// 用来取两位数的十位数字
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',
} ;
// 用来取不同进制的某一位数字
final static char[] digits = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
'o' , 'p' , 'q' , 'r' , 's' , 't' ,
'u' , 'v' , 'w' , 'x' , 'y' , 'z'
};
// 用来确定十进制位数
final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };

private final int value;

    // value是final的
Integer i = new Integer(10);
i = 5;
// 反编译之后
Integer i = new Integer(10);
i = Integer.valueOf(5);

三、构造方法

   // 两个构造方法  初始化一个Integer对象的时候只能创建一个十进制的整数
public Integer(int value) {
this.value = value;
} public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);

四、主要方法

Integer.valueof()

     /**
* 1.Integer类加载时,初始化一个-128到127的数组缓存
* 2.调用valueOf(int i)时,IntegerCache.cache中有直接取,IntegerCache.cache中没有需要new Integer
* 3.创建Integer时,Integer i = 5(编译后Integer i = Integer.valueOf(5));或者直接用Integer.valueOf(5)
* 4.-Djava.lang.Integer.IntegerCache.high=xxx就可以改变缓存值的最大值
*/ public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
} public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
} public static Integer valueOf(String s, int radix) throws NumberFormatException {
return Integer.valueOf(parseInt(s,radix));
} private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[]; static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
} private IntegerCache() {}
}

String--->Integer

    Integer getInteger(String nm)
Integer getInteger(String nm, int val)
Integer getInteger(String nm, Integer val)
Integer decode(String nm)
Integer valueOf(String s)
Integer valueOf(String s, int radix)
int parseUnsignedInt(String s)
int parseUnsignedInt(String s, int radix)
int parseInt(String s)
int parseInt(String s, int radix) // 调用栈
getInteger(String nm) ---> getInteger(nm, null);--->Integer.decode()--->Integer.valueOf()--->parseInt() // parseInt()主要代码
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
// 思路:357 = 3*10^2+5*10^1+7*10^0 = ((3*10+5)*10+7);
// 用负数计算原因:用正数计算表示不了Integer.MIN_VALUE = 0x80000000;

Integer--->String

   String toString()
static String toString(int i)
static String toString(int i, int radix)
static String toBinaryString(int i)
static String toHexString(int i)
static String toOctalString(int i)
static String toUnsignedString(int i)
static String toUnsignedString(int i, int radix) public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);// 计算字符数(根据sizeTable属性)
char[] buf = new char[size];
getChars(i, size, buf);// int-->char数组
return new String(buf, true);
} /**
* 计算字符数(根据sizeTable属性)
* 1.局部性原理之空间局部性:sizeTable为数组,存储在相邻的位置,cpu一次加载一个块数据数据到cache中(多个数组数据),此后访问sizeTable 不需要访问内存
* 2.基于范围的查找,是很实用的设计技术
*/
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++)
if (x <= sizeTable[i])
return i+1;
} /**
* int-->char数组
* 1.取余的思想
* 2.移位和加法的效率比直接乘除的效率要高,乘法的效率比除法的效率要高
* 3.分while for两段循环原因:大于65536的数乘52429超过int最大值,溢出
* 4.选52429原因:保证(i * num2) >>> (num3)结果接近于0.1,52429/2^19精度小
* 5.选65536原因:①65536=2^16 2^16 * 52429 < 2^32 < 2^17 * 52429
* ②q = (i * 52429) >>> (16+3); >>>无视符号位补0 --> i*52429只要小于2^32次方即可
* 6.r = i - ((q << 3) + (q << 1)); 移位和加法代替乘法
* q = (i * 52429) >>> (16+3); 移位和乘法代替除法
* buf [--charPos] = DigitOnes[r]; 直接取十位数字,代替再除一次取余
*/
static void getChars(int i, int index, char[] buf) {
int q, r;
int charPos = index;
char sign = 0; if (i < 0) {
sign = '-';
i = -i;
} // 每次循环过后,都会将i中的走后两位保存到字符数组buf中的最后两位中,读者可以将数字i设置为12345678测试一下,
// 第一次循环结束之后,buf[7] = 8,buf[6]=7。第二次循环结束之后,buf[5] = 6,buf[4] = 5。
while (i >= 65536) {
q = i / 100;
r = i - ((q << 6) + (q << 5) + (q << 2));// really: r = i - (q * 100);
i = q;
buf [--charPos] = DigitOnes[r];// 取DigitOnes[r]的目的其实取数字r%10的结果
buf [--charPos] = DigitTens[r];// 取DigitTens[r]的目的其实是取数字r/10的结果
} // 循环将其他数字存入字符数组中空余位置
for (;;) {
q = (i * 52429) >>> (16+3);// 这里其实就是除以10。取数52429和16+3的原因在后文分析。
r = i - ((q << 3) + (q << 1));// r = i-(q*10) ...
// 将数字i的最后一位存入字符数组,
// 还是12345678那个例子,这个for循环第一次结束后,buf[3]=4。
buf [--charPos] = digits [r];
i = q;
// for循环结束后,buf内容为“12345678”;
if (i == 0) break;
}
if (sign != 0) {
buf [--charPos] = sign;
}
}
    Integer s = new Integer(5);
System.out.println(s + "");
// 反编译:
Integer s = new Integer(5);
System.out.println((new StringBuilder()).append(s).append("").toString());

五、其他方法

    // 无符号转换
public static long toUnsignedLong(int x) {
return ((long) x) & 0xffffffffL;
} /**
* 该方法主要用于计算二进制数中1的个数。
* 0x55555555等于01010101010101010101010101010101,0x33333333等于110011001100110011001100110011,0x0f0f0f0f等于1111000011110000111100001111。
* 它的核心思想就是先每两位一组统计看有多少个1,比如10011111则每两位有1、1、2、2个1,记为01011010,然后再算每四位一组看有多少个1,而01011010则每四位有2、4个1,记为00100100,接着每8位一组就为00000110,接着16位,32位
* 最终在与0x3f进行与运算,得到的数即为1的个数。
*/
public static int bitCount(int i) {
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
} /**
* 该方法返回i的二进制中最高位的1,其他全为0的值。
* 比如i=10时,二进制即为1010,最高位的1,其他为0,则是1000。如果i=0,则返回0。如果i为负数则固定返回-2147483648,因为负数的最高位一定是1,即有1000,0000,0000,0000,0000,0000,0000,0000。
* 将i右移一位再或操作,则最高位1的右边也为1了,接着再右移两位并或操作,则右边1+2=3位都为1了,接着1+2+4=7位都为1,直到1+2+4+8+16=31都为1,最后用i - (i >>> 1)自然得到最终结果。
*/
public static int highestOneBit(int i) {
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
} /**
* 获取最低位1,其他全为0的值。
* 先取负数,这个过程需要对正数的i取反码然后再加1,得到的结果和i进行与操作,刚好就是最低位1其他为0的值了
*/
public static int lowestOneBit(int i) {
return i & -i;
} /**
* 该方法返回i的二进制从头开始有多少个0。i为0的话则有32个0。
* 这里处理其实是体现了二分查找思想的,先看高16位是否为0,是的话则至少有16个0,否则左移16位继续往下判断,接着右移24位看是不是为0,是的话则至少有16+8=24个0,直到最后得到结果。
*/
public static int numberOfLeadingZeros(int i) {
if (i == 0)
return 32;
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
} /**
* 该方法返回i的二进制从尾开始有多少个0。它的思想和前面的类似,也是基于二分查找思想,详细步骤不再赘述。
*/
public static int numberOfTrailingZeros(int i) {
int y;
if (i == 0) return 32;
int n = 31;
y = i <<16; if (y != 0) { n = n -16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
return n - ((i << 1) >>> 31);
} /**
* 该方法即是将i进行反转,反转就是第1位与第32位对调,第二位与第31位对调,以此类推。
* 它的核心思想是先将相邻两位进行对换,比如10100111对换01011011,接着再将相邻四位进行对换,对换后为10101101,接着将相邻八位进行对换,最后把32位中中间的16位对换,然后最高8位再和最低8位对换。
*/
public static int reverse(int i) {
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}

参考资料:

1、Java 源码学习系列(三)——Integer

2、Java源码 Integer.bitCount实现过程

3、Java中byte做&0xff运算的原因及解析

4、从JDK源码角度看Integer

5、Integer源码详解

JDK源码学习笔记——Integer的更多相关文章

  1. JDK源码学习笔记——LinkedHashMap

    HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序. LinkedHashMap保证了元素迭代的顺序.该迭代顺序可以是插入顺序或者是访问顺序.通过维护一个 ...

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

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

  3. JDK源码学习笔记——Object

    一.源码解析 public class Object { /** * 一个本地方法,具体是用C(C++)在DLL中实现的,然后通过JNI调用 */ private static native void ...

  4. JDK源码学习笔记——Enum枚举使用及原理

    一.为什么使用枚举 什么时候应该使用枚举呢?每当需要一组固定的常量的时候,如一周的天数.一年四季等.或者是在我们编译前就知道其包含的所有值的集合. 利用 public final static 完全可 ...

  5. JDK源码学习笔记——HashMap

    Java集合的学习先理清数据结构: 一.属性 //哈希桶,存放链表. 长度是2的N次方,或者初始化时为0. transient Node<K,V>[] table; //最大容量 2的30 ...

  6. jdk源码阅读笔记-Integer

    public final class Integer extends Number implements Comparable<Integer> Integer 由final修饰了,所以该 ...

  7. JDK源码学习笔记——HashSet LinkedHashSet TreeSet

    你一定听说过HashSet就是通过HashMap实现的 相信我,翻一翻HashSet的源码,秒懂!! 其实很多东西,只是没有静下心来看,只要去看,说不定一下子就明白了…… HashSet 两个属性: ...

  8. JDK源码学习笔记——TreeMap及红黑树

    找了几个分析比较到位的,不再重复写了…… Java 集合系列12之 TreeMap详细介绍(源码解析)和使用示例 [Java集合源码剖析]TreeMap源码剖析 java源码分析之TreeMap基础篇 ...

  9. JDK源码学习笔记——LinkedList

    一.类定义 public class LinkedList<E> extends AbstractSequentialList<E> implements List<E& ...

随机推荐

  1. MNIST数据集转化为二维图片

    #coding: utf-8 from tensorflow.examples.tutorials.mnist import input_data import scipy.misc import o ...

  2. 过渡&动画

    进入/离开&列表过渡 概述 Vue在插入,更新或者移除Dom时,提供多种不同方式的应用过渡效果.包括以下工具 在css过渡和动画中自动应用class 可以配合使用第三方css动画库,如Anim ...

  3. Android SDK更新 Connection to http://dl-ssl.google.com refused

    问题: Failed to fetch URL https://dl-ssl.google.com/android/repository/repository-6.xml, reason: Conne ...

  4. 学习1:python输入输出

    1. 输出 >>> print "hello world" hello world >>> print 'hello world' hello ...

  5. C# 笔记——索引器

    索引器允许类或者结构的实例按照与数组相同的方式进行索引取值,索引器与属性类似,不同的是索引器的访问是带参的. 索引器和数组比较: (1)索引器的索引值(Index)类型不受限制 (2)索引器允许重载 ...

  6. phpcms v9表单向导添加验证码

    要做留言板的功能,故用添加表单,想要在提交留言前加一个验证码的功能.网上的教程比较混乱,于是亲自实验了下,步骤如下: 首先是调用表单的页面加入验证码.表单js调用模版默认的是 \phpcms\temp ...

  7. hdu 2883(构图+最大流+压缩区间)

    kebab Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  8. 一款简洁而强大的前端框架—JQuery

    jQuery是什么? jQuery是一个快速.简洁的JavaScript框架,它封装JavaScript常用的功能代码,提供一种简便的JavaScript设计模式,优化HTML文档操作.事件处理.动画 ...

  9. javascript大神修炼记(4)——循环

    读者朋友们大家好,今天,我们继续接着前面的内容讲,前们我们已经讲了条件分支,今天我们就讲循环,顾名思义就是,重复执行相同的操作,正常循环是受程序控制的,不正常的情况,就会出现死循环,那就是我们的代码中 ...

  10. Mac安装Maven

    1.从官网(https://maven.apache.org/download.cgi)下载 Maven 并解压. 2.配置环境 .  vim ~/.bash_profile export MAVEN ...