Java: Integer vs int
Definitions
An int is a primitive. It is not an Object. An int is a high performance, streamlined beast for calculating numbers in the range -2,147,483,648 [-231] aka Integer.MIN_VALUE to +2,147,483,647 [2 31-1] aka Integer.MAX_VALUE. An int is a bare bones 32-bit chunk of information. int variables are mutable. Unless you mark them final, you can change their value at any time.
An Integer, is a Object that contains a single int field. An Integer is much bulkier than an int. It is sort like a Fedex box to contain the int. Integers are immutable. If you want to affect the value of a Integer variable, the only way is to create a new Integer object and discard the old one.
An int
is a number; an Integer
is a pointer that can reference an object that contains a number.
Converting
Fortunately it is easy to convert back and forth between int and Integer.
// to int i from Integer ii int i = ii.intValue(); // to Integer ii from int i Integer ii = new Integer( i );
See this Amanuensis for other conversions.
Why Both?
Why are there both int and Integer? For speed. ints, without any Object packaging are compact and fast. Would it not have been easier if there were only one of sort of creature that could do everything and have the compiler automatically figure out when the packaging was needed and when not? The Eiffel language designers thought so, and the Java designers are gradually coming around to the same conclusion.
Integer是引用类型,int是原生数据类型。
我们分四种情况来讨论:
1) Integer与int类型的赋值
a.把Integer类型赋值给int类型。此时,int类型变量的值会自动装箱成Integer类型,然后赋给Integer类型的引用,这里底层就是通过调用valueOf()这个方法来实现所谓的装箱的。
b.把int类型赋值给Integer类型。此时,Integer类型变量的值会自动拆箱成int类型,然后赋给int类型的变量,这里底层则是通过调用intValue()方法来实现所谓的拆箱的。
2) Integer与int类型的比较
这里就无所谓是谁与谁比较了,Integer == int与int == Integer的效果是一样的,都会把Integer类型变量拆箱成int类型,然后进行比较,相等则返回true,否则返回false。同样,拆箱调用的还是intValue()方法。
3) Integer之间的比较
这个就相对简单了,直接把两个引用的值(即是存储目标数据的那个地址)进行比较就行了,不用再拆箱、装箱什么的。
4) int之间的比较
这个也一样,直接把两个变量的值进行比较。
值得注意的是:对Integer对象,JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个;超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存。
测试代码如下:
public static void main(String[] args) throws Exception { Integer a = 127, b = 128; int c = 128; //自动装箱,这里会调用Integer中的valueOf方法把c装箱成Integer类型 a = c; //这里比较的是两个对象的地址,显然不等 System.out.println(a == b); //这里会调用Integer的intValue方法获得Integer对象a指向的栈地址中存的值再与c进行值比较, //而不是把c装箱成Integer类型进行地址比较 System.out.println(a == c); //同上,也是获得a指向的栈地址中存的值 System.out.println(c == a); /** * 总结:只有在赋值(=)的时候才会出现装箱和拆箱两种情况, * 在比较(==)的时候只会出现一种情况,那就是拆箱,而不会出现装箱的情况 */ System.out.println("----------------------------------"); Integer i1 = 127; Integer i2 = 127; System.err.println(i1 == i2); i1 = 128; i2 = 128; System.err.println(i1 == i2); /** * 总结:JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个; * 超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存,这样做是为了节省内存消耗。 */ }