int 是 Java 八大原始类型之一,是 Java 语言中为数不多不是对象的东西,Integer 是 int 的包装类,里面使用了一个 int 类型的变量来存储数据,提供了一些整数之间的常用操作,常规性的介绍就这么一点,程序员不喜欢说,程序员就喜欢源码,我们还是来看源码吧

 * @author  Lee Boynton
* @author Arthur van Hoff
* @author Josh Bloch
* @author Joseph D. Darcy
* @since JDK1.0
*/
public final class Integer extends Number implements Comparable<Integer> {
/**
* A constant holding the minimum value an {@code int} can
* have, -2<sup>31</sup>.
*/
@Native public static final int MIN_VALUE = 0x80000000; /**
* A constant holding the maximum value an {@code int} can
* have, 2<sup>31</sup>-1.
*/
@Native public static final int MAX_VALUE = 0x7fffffff; /**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value; /**
* Constructs a newly allocated {@code Integer} object that
* represents the specified {@code int} value.
*
* @param value the value to be represented by the
* {@code Integer} object.
*/
public Integer(int value) {
this.value = value;
} /**
* Constructs a newly allocated {@code Integer} object that
* represents the {@code int} value indicated by the
* {@code String} parameter. The string is converted to an
* {@code int} value in exactly the manner used by the
* {@code parseInt} method for radix 10.
*
* @param s the {@code String} to be converted to an
* {@code Integer}.
* @exception NumberFormatException if the {@code String} does not
* contain a parsable integer.
* @see java.lang.Integer#parseInt(java.lang.String, int)
*/
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}

上面这段源码是我截取出来的,在 Integer 类中,这些代码不是连在一起的,把他们放在一起,那是因为我想说明点事情,我们仔细看看这段代码,Integer 类是被 final ,这说明了什么?用于存放变量的 value 也被 private final 修饰,这又说明了什么?看着这些是不是有点熟悉呢? 没错,String 对象也是这样的,这说明 Integer 对象也是不可变的,所以以后如果被问到 Integer 对象是不是不可变对象时,记得回答是喔。为什么 Integer 对象也会设计成不可变对象呢?其实我也不知道,我没有从文档中找到答案,但是在杨晓峰老师的文章中看到过有关说明,杨晓峰老师说 Integer 类设计成不可变跟 getInteger() 方法有关系,getInteger()方法的源码如下:

public static Integer getInteger(String nm, Integer val) {
String v = null;
try {
v = System.getProperty(nm);
} catch (IllegalArgumentException | NullPointerException e) {
}
if (v != null) {
try {
return Integer.decode(v);
} catch (NumberFormatException e) {
}
}
return val;
}

getInteger() 方法是用来获取系统属性的,我们通过属性来设置服务器的某个服务器的端口,如果 Integer 可变的话,那么我们就能够轻易的改变这个属性的值,这会使得我们的产品存在安全风险。

上面我们我么简单的聊了一下 Integer 类的实现,聊到 int 与 Integer,自然就少不了自动装箱和自动拆箱。

1、自动装箱、拆箱

自动装箱和拆箱是从 JDK 1.5 开始引进的功能,它是一种语法糖,Java 可以根据上下文,自动的在原始类型和包装类型中进行转换,简单的来说就是 Java 平台保证了不同的写法通过编译之后会产生相同的字节码,保证了运行时是等价的。自动装箱和拆箱极大地简化了相关编程。

自动装箱:将原始类型转化为包装类型的过程

比如将 int 类型转换成 integer 类型,这就是原始类型到包装类型的转变,在编译的时候,编译器就会帮我们做自动转换,这个过程对我们程序员来说是无感知的,例如这段给 Integer 对象赋值的代码:

Integer x = 3000;

这段代码经过编译器之后,会转换成下面这段代码:

Integer x = Integer.valueOf(3000);

这就是自动装箱过程,这个过程你是不知道的,所以它才叫自动装箱,在自动装箱的过程中使用到了 valueOf() 方法,来看看 JDK 中这个方法的源码:

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

这个方法里,前面先进行了一个缓存判断,如果你不知道的话,先忽略掉它,最后返回了 new Integer(i) 对象引用,这个方法就是帮你去调用了 Integer 类的构造器。这就是自动装箱。

自动拆箱:将包装类型转换成原始类型的过程

将 Integer 类型转换为 Int 类型,这是一个包装类型转成成原始类型的过程,在这个过程中就会涉及到自动拆箱。来看看这段代码(这是一段很操蛋的代码,实际中应该没人这样写):

Integer mm = 1000;
int mmm = mm;

在编译的时候,这段代码会被编译器编译成下面这段代码:

Integer mm = Integer.valueOf(1000);
int mmm = mm.intValue();

主要看int mmm = mm.intValue();这行代码,这行代码跟我们写的不一样了,使用到了一个 intValue() 方法,来看看 Integer 类中 intValue() 方法的源码:

/**
* Returns the value of this {@code Integer} as an
* {@code int}.
*/
public int intValue() {
return value;
}

这个方法的作用就是把 Integer 对象中用来存储值的 value 变量返回了,这就是自动拆箱,好了,关于自动装箱和自动拆箱我们都了解了,还记得自动装箱过程中涉及到的缓存吗?接下来我们一起了解一下。

2、Integer 缓存策略

在自动装箱的 valueOf() 方法中,我们看到了有一个缓存判断的操作,是的,Integer 类中有缓存池,会将使用频繁的值缓存起来,以便提高系统的使用性能,在自动装箱的过程中,会先判断该值是否存在缓存池中,如果存在直接从缓存池中取出引用返回,如果不存在则调用构造函数构造对象。缓存是自动装箱操作独享的,直接通过构造函数构造出来的 Integer 对象即使值在缓存范围内,也不会使用到缓存池。在 Integer 类中,使用了一个内部类来实现缓存,这个内部类叫做 IntegerCache,IntegerCache 类的源代码如下:

    /**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/ 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() {}
}

从源码和 Java 注释中我们可以看出 IntegerCache 的缓存默认值范围 -128 ~ 127 。但是我们也可以在启动时通过 JVM 命令来设置缓存范围的最大值,只需要在启动时添加 -XX:AutoBoxCacheMax=

参数就可以了,但是记得这个 size 可不要乱设置,需要全方位考虑,比如你设置成 10 万,那么这 10 万个数都会在启动刚启动时就添加到内存中,想想这会占用你多少内存?这样做就得不偿失了,Java 公司设置成 -128 ~ 127 是有道理的,发现大部分人使用的值都在 -128 ~ 127 之间,这些值占用的内存比较少,性能上比通过构造函数构造对象要好不少。如何你使用的 Integer 的值在缓存范围的话,就用 Integer i = value 的形式构建对象,如果你的值不在缓存范围内,则使用 Integer i = new Integer(value) 的形式构建 Integer 对象,避免自动装箱的过程。最后我们来看一下 Integer 对象比较常用的方法 parseInt 方法

3、parseInt() 方法

parseInt() 方法的作用是用来将整数型的字符串转换成整数,parseInt 方法需要和 valueOf 方法区分开来,有不少人会问这两方法有什么区别,最后度会返回 int 类型,都能将整数型的字符串转换成整数型,比如这段代码

System.out.println(Integer.parseInt("+12"));
System.out.println(Integer.valueOf("+12"));

最后都会输出 12 ,输出的结果相同是因为 valueOf 方法使用中会调用 parseInt 方法将整数型字符转换为整数,并且会在内存中创建一个值为 12 的 Integer 对象,然后返回这个对象引用。而 parseInt 方法只会帮你将整数型字符转换为整数,不会额外的创建对象。所以它们两得到相同的结果纯属是巧合。一起瞅瞅 parseInt 源代码:

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");
} 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;
int i = 0, len = s.length();
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;
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;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}

在调用 parseInt 方法时,我们可以传入一个 radix 变量,用来告诉它使用什么进制来进行转换,默认使用的是十进制。

文章不足之处,望大家多多指点,共同学习,共同进步

最后

打个小广告,欢迎扫码关注微信公众号:「平头哥的技术博文」,一起进步吧。

从 Int 到 Integer 对象,细细品来还是有不少东西的更多相关文章

  1. Java中int与Integer的区别

    转自https://www.cnblogs.com/guodongdidi/p/6953217.html import java.lang.Integer; public class intDemo{ ...

  2. int与Integer的爱恨情仇

    int作为java中元老级的数据类型,可谓无处不在,自从jdk5诞生了Integer,从此不在孤单. 为什么要设计Integer呢?它与int有什么区别? 一.Integer是int的包装类型,是引用 ...

  3. java int与integer的区别

    int与integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象 1.Java 中的数据类型分为基本数据类型 ...

  4. [转载]java int与integer的区别

    声明: 本篇文章属于转载文章,来源:

  5. java integer对象判断两个数字是否相等

    java integer对象判断两个数字是否相等,不一定对 问题发生的背景:javaweb的项目,起先,因为在java中实体类中的int类型在对象初始化之后会给int类型的数据默认赋值为0,这样在很多 ...

  6. int 与Integer的用法与区别

    1.int是基本类型,直接存取数值,Integer是对象,用一个引用指向这个对象. 2.java中的数据类型分为基本数据类型和复杂数据类型,int是前者,Integer是后者(也就是一个类). 3.初 ...

  7. int和integer的比较

    程序代码: Integer i01 = 59; int i02 = 59; Integer i03 =Integer.valueOf(59); Integer i04 = new Integer(59 ...

  8. 【转】java int与integer的区别

    java int与integer的区别 int与integer的区别从大的方面来说就是基本数据类型与其包装类的区别: int 是基本类型,直接存数值,而integer是对象,用一个引用指向这个对象 1 ...

  9. Integer对象

    数字格式的字符串转成基本数据类型的方法: 1:将该字符串封装成了Integer对象,并调用对象的方法intValue(); 2:使用Integer.parseInt(numstring):不用建立对象 ...

随机推荐

  1. 【码上开心】Windows环境mysql数据库使用(一) 安装Mysql数据库

    [下载MySql] https://dev.mysql.com/downloads/mysql/ 如下图,选择版本,本教程仅演示ZIP压缩包下载配置. 2.[解压到指定目录] 3.[配置环境变量] 4 ...

  2. C#开发BIMFACE系列4 服务端API之源上传文件

    在注册成为BIMFACE的应用开发者后,要能在浏览器里浏览你的模型或者获取你模型内的BIM数据, 首先需要把你的模型文件上传到BIMFACE.根据不同场景,BIMFACE提供了丰富的文件相关的接口. ...

  3. Leetcode之二分法专题-744. 寻找比目标字母大的最小字母(Find Smallest Letter Greater Than Target)

    Leetcode之二分法专题-744. 寻找比目标字母大的最小字母(Find Smallest Letter Greater Than Target) 给定一个只包含小写字母的有序数组letters  ...

  4. ubuntu 用户无法/循环登陆的问题

    安装oracle数据库的时候需要新建用户oracle,使用的命令为:useradd oracle.这样做直接创建了用户oracle,但并没有在home目录下创建oracle用户的文件.在log out ...

  5. MySQL 5.7 的安装历程

    mysql5.7零基础入门级的安装教程: 安装环境:Windows 10, 64 位(联想拯救者R720) 安装版本:mysql-5.7.25-winx64 一.下载 1.进入官网 首先,下载MySQ ...

  6. Unity的UGUI在SetParent后修改UI的localposition问题

    正常情况下,UGUI设置UI的localposition可以直接赋值 UIxxx.rectTransform.localPosition = ] / 2f, , ); 运行后在Unity的Inspec ...

  7. Linux 下安装 mysql8

    1.下载mysql wget https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.13-linux-glibc2.12-x86_64.tar 2. ...

  8. 持续集成高级篇之Jenkins资源调度

    系列目录 之前的示例我们主要关注点在于功能的实现,都是在一个节点的完成了.有了多个节点后,必须涉及到资源的调度问题.本节我们讲解在创建任务时与资源调度的有关选项以及一些平时没有注意到的但在生产环境需要 ...

  9. D-Big Integer_2019牛客暑期多校训练营(第三场)

    题意 设A(n) = n个1,问有多少对i,j使得\(A(i^j)\equiv0(modp)\) 题解 \(A(n) = \frac{10^n-1}{9}\) 当9与p互质时\(\frac{10^n- ...

  10. HDU-6333 Problem B. Harvest of Apples 莫队

    HDU-6333 题意: 有n个不同的苹果,你最多可以拿m个,问有多少种取法,多组数据,组数和n,m都是1e5,所以打表也打不了. 思路: 这道题要用到组合数的性质,记S(n,m)为从n中最多取m个的 ...