int
- Java基本数据类型
- 直接存储为数据值,保存在栈中
- 无需初始化,默认值为0
Integer
- 包装类,基本数据类型int的包装类
- 对象,存储为对象在内存的引用,对象的引用保存在栈中,数据存储在堆内存中
- 对象,必须初始化才可以使用,默认值为null
重点知识点
基本数据类型
分为boolean、byte、int、char、long、short、double、float;
引用数据类型
Java原始类型的封装类
为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每 一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
自动装箱和自动拆箱
自动装箱:将基本数据类型重新转化为对象
自动拆箱:将对象重新转化为基本数据类型
相同值下的 int 和 Integer 的比较结果
两个通过new生成的变量,结果为false。
Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
System.out.print(i1 == i2); //false
int 和 Integer 的值比较,若两者的值相等,则为true。(注意:在比较时,Integer会自动拆箱为int类型,然后再做比较,实际上就变为两个int变量的比较)
Integer i1 = new Integer(10);
int i2 = 10;
System.out.print(i1 == i2); //true
new 生成的Integer变量 和 非new 生成的Integer变量比较,结果为false。(注意:new 生成的Integer变量的值在堆空间中,非new 生成的Integer变量的值在在常量池中。非new生成的Integer变量,会先判断常量池中是否有该对象,若有则共享,若无则在常量池中放入该对象;这也叫享元模式)
Integer i1 = new Integer(10);
Integer i2 = 10;
System.out.print(i1 == i2); //false
对于两个非new生成的Integer对象,进行比较时,如果两个变量的值在区间-128到127之间,则比较结果为true,如果两个变量的值不在此区间,则比较结果为false。
Integer i1 = 10;
Integer i2 = 10;
System.out.print(i1 == i2); //true
Integer j1 = 128;
Integer j2 = 128;
System.out.print(j1 == j2); //false
复制代码
当值在 -128 ~ 127之间时,java会进行自动装箱,然后会对值进行缓存,如果下次再有相同的值,会直接在缓存中取出使用。缓存是通过Integer的内部类IntegerCache来完成的。当值超出此范围,会在堆中new出一个对象来存储。
源码分析
Integer 类中有2种构造方法,如下:
2个构造方法都比较清晰,将输入的值初始化赋值
/**
* 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);
}
JDK1.5之后,java提供了自动装箱和自动拆箱的功能。自动装箱也就是调用了Integer类的一个静态方法valueOf
方法,源码如下:
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
其中可以看到,针对参数i进行了IntegerCache.low和IntegerCache.high的比较,如果在此范围内,则直接返回cache数组中的内容,如果不在此范围内,则new一个新的Integer对象返回。
我们继续看IntegerCache类具体做了哪些内容。
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() {}
}
在上面源码可以清晰的看到,IntegerCache中有3个常量,low为最小范围,high为最大范围,cache数组缓存了基本数据内容,其次,IntegerCache中还有一个静态代码块,用来初始化以上数据内容。
如果VM环境设置了java.lang.Integer.IntegerCache.high变量,则high=设置的值如果小于127则取127,如果大于Integer.MAX_VALUE-128-1,则取Integer.MAX_VALUE-128-1。
最后会根据大小初始化cache数据内容,这些数据都是static,会保存在栈内存中。
- 缓存支持自动装箱的对象标识语义 -128 <= i <= 127
- 缓存在第一次使用时初始化。 缓存的大小可以由-XX:AutoBoxCacheMax = 选项控制
- 在VM初始化期间,java.lang.Integer.IntegerCache.high属性可以设置并保存在私有系统属性