Integer类的申明

public final class Integer extends Number implements Comparable<Integer> { … }

Integer用于对int类型数值的封装,并提供一些int类型数据操作的方法,Integer继承自Number类,Number是JDK的一个代表数值的超类,提供一些用于不同数值之间类型转换方法,常见的数值类型Double、Float等都继承自Number

Integer还实现了Comparable接口,主要用于Integer对象之间比较。

Integer字段、属性说明

Integer是对int型数值的封装,int型,占4个字节(JDK中定义占4字节),每个字节8位因次是32位,再除去一个符号位,因此范围是-2^31~2^31-1

下面列举几个重要的字段解释一下:

    /**
*代表Integer封装的int整形数值
*/
private final int value; /**
*限制Integer对象存放最小值 -2^31
*/
@Native public static final int MIN_VALUE = 0x80000000; /**
* //限制Integer对象存放最大值 2^31-1
*/
@Native public static final int MAX_VALUE = 0x7fffffff; /**
*表示int二进制补码形式的值的位数。
*/
@Native public static final int SIZE = 32; /**
* 用于以int二进制补码形式表示值的字节数32/8 = 4字节
*/
public static final int BYTES = SIZE / Byte.SIZE;

Integer 部分方法分析

Integer类内部提供了很多方法,用于数值转换等操作,下面仍然是列举几个经常用到的分析一下实现过程:

构造函数Integer(String s)

/**
* 构造函数,允许传入一个字符串,通过内部函数parseInt尝试将其转成10进制int型数值,默认转成10进制,如果传入的String无法转换成Int则跑出异常
*/
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}

int parseInt(String s, int radix)方法

将字符串参数解析为指定的几进制带符号整数,转换失败抛出异常,string参数:将要转换为数值的字符串,int参数:代表需要转换的是几进制数值

JDK源码注释中给出一些示例:

    /**
* JDK源码注释中的示例:
* <p>Examples:
* <blockquote><pre>
* parseInt("0", 10) returns 0
* parseInt("473", 10) returns 473
* parseInt("+42", 10) returns 42
* parseInt("-0", 10) returns 0
* parseInt("-FF", 16) returns -255
* parseInt("1100110", 2) returns 102
* parseInt("2147483647", 10) returns 2147483647
* parseInt("-2147483648", 10) returns -2147483648
* parseInt("2147483648", 10) throws a NumberFormatException
* parseInt("99", 8) throws a NumberFormatException
* parseInt("Kona", 10) throws a NumberFormatException
* parseInt("Kona", 27) returns 411787
*/
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.
*/ //字符串为空直接异常
if (s == null) {
throw new NumberFormatException("null");
} //判断radix合法性,Integer内部允许2进制-36进制之间转换
//为什么是36进制? 看个示例
// Integer.parseInt("A", 16) = 10
    // Integer.parseInt("a", 16) =10
    // 上面可以看出不区分大小写,是不是10个数字+26个母?
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");
} int result = 0; //返回结果
boolean negative = false; //符号,正数or负数
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit; //字符串长度大于0
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); //长度是1,只有符号位,没有数值,抛异常
i++;
}
multmin = limit / radix;
//遍历字符转,从最高位开始,整个过程以负数计算,逐位乘以单位制,最后再修正符号位,以10进制数123为例。转换过程如下
// result = -1
// result = -1*10-2 = -12
// result = -12*10-3 = -123
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(s.charAt(i++),radix); //将字符转换为radix进制数值,比如Character.digit(‘c’,16) = 12
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;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result; //修正符号位
}

其他parseInt相关方法也都是调用这个最基础的方法进行转换。

Integer valueOf(int i)方法

返回指定int值的Integer实例,如果Integer不需要新实例,可优先使用此方法,而不是构造函数,因为此方法会缓存经常请求的值的Integer实例。该方法将始终缓存-128至127(含)范围内的值,并可缓存此范围之外的其他值

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

Valueof方法内部使用了IntegerCache,判断如果数值在[IntegerCache.low, IntegerCache.high]这个范围内,则从缓存中读取,否则调用构造函数创建一个Integer实例

private static class IntegerCache {
static final int low = -128; //最小值 -128
static final int high; //最大值
static final Integer cache[]; //静态代码块,在Integer类加载时就已经缓存好
static {
// high value may be configured by property
int h = 127; //最大值 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); //在配置参数和默认h中取最大值
// 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++); //缓存integer对象 // range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
} private IntegerCache() {}
}

Valueof()方法完成将int型转换成Integer对象,其实就是一个装箱操作,Integer类型也可以直接赋值一个int数值:Integer integer = 100 这其实就是通过调用valueof()方法完成的。

相对应的方法:int intValue() 获取Integer对象内部value值,其实就是完成一个拆箱操作

public int intValue() {
return value;
}

下面给出一组测试示例,通过对Integer对比分析一下Integer对象的装箱拆箱和IntegerCache缓存:

        Integer integer0 = Integer.valueOf(1);   //IntegerCache缓存中读取
Integer integer1 = new Integer(1); //创建新实例
Integer integer2 = new Integer(1); //创建新实例
System.out.println(integer1.equals(integer2)); //true Integer.equal内部实现并不是比较两个Integer对象的引用,而是比较Integer.value值是否相等
System.out.println(integer1==integer2); //false integer1和integer2是两个不同的对象,引用不一样 Integer integer3 = 1;
Integer integer4 = 1;
System.out.println(integer3 == integer4);//true,integer3和integer4都完成装箱,从IntegerCache中取出相同的实例 Integer integer8 = 128;
Integer integer9 = 128;
System.out.println(integer8 == integer9);//false,integer8和integer9都完成装箱,New Integer(128)==new Integer(128) System.out.println(integer3 == integer1);//false,integer3通过调用valueof做了装箱操作 实际相当于 Integer.valueOf(1)==integer1
System.out.println(integer3 == integer0);//true,integer3通过调用valueof做了装箱操作 实际相当于 Integer.valueOf(1)==integer0 ,都从IntegerCache缓存中读取 int integer5 = 1;
Integer integer6 = new Integer(1); System.out.println(integer5 == integer5);//true 当Integer对象和int比较时,Integer对象调用intValue完成自动拆箱,转换为int,相当于两个int型比较 Integer integer7 = 1;
System.out.println(integer7==integer5); //true integer7先装箱,比较时又做了拆箱操作

Integer和int的区别

Integer是对int型封装后的类,int是java的一种基本数据类型(byte,char,short,int,long,float,double,boolean)

    Integer是对象的引用,默认值为null,实例化后是一个对象的引用,指向存放该对象的地址,int作为基本数据类型,默认值为0

												

JDK源码分析 – Integer的更多相关文章

  1. JDK源码分析-Integer

    Integer是平时开发中最常用的类之一,但是如果没有研究过源码很多特性和坑可能就不知道,下面深入源码来分析一下Integer的设计和实现. Integer: 继承结构: -java.lang.Obj ...

  2. JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue

    JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue 目的:本文通过分析JDK源码来对比ArrayBlockingQueue 和LinkedBlocki ...

  3. JDK 源码分析(4)—— HashMap/LinkedHashMap/Hashtable

    JDK 源码分析(4)-- HashMap/LinkedHashMap/Hashtable HashMap HashMap采用的是哈希算法+链表冲突解决,table的大小永远为2次幂,因为在初始化的时 ...

  4. 【JDK】JDK源码分析-HashMap(1)

    概述 HashMap 是 Java 开发中最常用的容器类之一,也是面试的常客.它其实就是前文「数据结构与算法笔记(二)」中「散列表」的实现,处理散列冲突用的是“链表法”,并且在 JDK 1.8 做了优 ...

  5. 【JDK】JDK源码分析-Vector

    概述 上文「JDK源码分析-ArrayList」主要分析了 ArrayList 的实现原理.本文分析 List 接口的另一个实现类:Vector. Vector 的内部实现与 ArrayList 类似 ...

  6. 【JDK】JDK源码分析-ArrayList

    概述 ArrayList 是 List 接口的一个实现类,也是 Java 中最常用的容器实现类之一,可以把它理解为「可变数组」. 我们知道,Java 中的数组初始化时需要指定长度,而且指定后不能改变. ...

  7. 【JDK】JDK源码分析-CountDownLatch

    概述 CountDownLatch 是并发包中的一个工具类,它的典型应用场景为:一个线程等待几个线程执行,待这几个线程结束后,该线程再继续执行. 简单起见,可以把它理解为一个倒数的计数器:初始值为线程 ...

  8. 【JDK】JDK源码分析-HashMap(2)

    前文「JDK源码分析-HashMap(1)」分析了 HashMap 的内部结构和主要方法的实现原理.但是,面试中通常还会问到很多其他的问题,本文简要分析下常见的一些问题. 这里再贴一下 HashMap ...

  9. JDK源码分析(三)—— LinkedList

    参考文档 JDK源码分析(4)之 LinkedList 相关

随机推荐

  1. JS继续学习记录(一)

    JS继续学习记录(一) 总感觉自己的js code写的还算可以,但是又深知好像只知道一些皮毛,所以打算仔细记录一下js晋级学习过程,日日往复 先记录一下自己目前对js的了解吧(20180828) js ...

  2. jquery mobile 移动web(6)

    jquery mobile 针对移动端设备的事件类型. 1.touch 事件. tap 快速触摸屏幕并且离开,类似一种完整的点击操作. taphold 触摸屏幕并保持一段时间. swipe 在1秒内水 ...

  3. c/c++面试总结---c语言基础算法总结2

    c/c++面试总结---c语言基础算法总结2 算法是程序设计的灵魂,好的程序一定是根据合适的算法编程完成的.所有面试过程中重点在考察应聘者基础算法的掌握程度. 上一篇讲解了5中基础的算法,需要在面试之 ...

  4. 【PTA 天梯赛】L2-016. 愿天下有情人都是失散多年的兄妹(深搜)

    呵呵.大家都知道五服以内不得通婚,即两个人最近的共同祖先如果在五代以内(即本人.父母.祖父母.曾祖父母.高祖父母)则不可通婚.本题就请你帮助一对有情人判断一下,他们究竟是否可以成婚? 输入格式: 输入 ...

  5. git设置.gitignore文件

    .gitignore用来忽略某些git仓库中不需要上传到远程仓库的文件,例如target目录.下面说一下步骤. 1.在项目根目录中通过右键Git Bash,打开控制命令台,新建一个.gitignore ...

  6. nginx: [error] open() "/var/run/nginx.pid" failed (2: No such file or directory)

    解决办法: nginx nginx -s reload

  7. webpack3构建全面提速优化vue-cli

    前言 伴随着vue的全球化,各种vue的组件框架越来越完善,从早期的element-ui到vux,iview等越来越多高质量的项目,使用vue进行前端构建已然是一件工程化,模块化,敏捷化的事情 在这其 ...

  8. php file_exists中文路径不存在问题

    php的file_exists函数使用中文路径,会显示文件不存在,即使文件已经存在了也会报这个错. 解决方法: <?php $file_name='D://360极速浏览器下载//a.txt'; ...

  9. Linux mysql启动与关闭

    service mysql stop service mysqld start

  10. 图片验证码给AI使用

    为了破解图形验证码,AI需要大量的图片数据.为了简单获取大量的图形来喂给Ai模型训练,索性自己写一把.代码来一发..   import java.awt.Color; import java.awt. ...