先看一个例子:
public class test {
public static void main(String args[]){
Integer c1 = 1;
Integer d1 = 1;
int c2 = 1;
int d2 = 1;
Integer c3 = 300;
Integer d3 = 300;
int c4 = 300;
int d4 = 300;
System.out.println(c1==d1);
System.out.println(c2==d2);
System.out.println(c3==d3);
System.out.println(c4==d4);
}
}
输出结果
import java.io.PrintStream;
public class test
{
public static void main(String[] paramArrayOfString)
{
Integer localInteger1 = Integer.valueOf(1);
Integer localInteger2 = Integer.valueOf(1);
int i = 1;
int j = 1;
Integer localInteger3 = Integer.valueOf(300);
Integer localInteger4 = Integer.valueOf(300);
int k = 300;
int m = 300;
System.out.println(localInteger1 == localInteger2);
System.out.println(i == j);
System.out.println(localInteger3 == localInteger4);
System.out.println(k == m);
}
}
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
也就是当数字大于-128小于IntegerCache.high时直接从IntegerCache中取值,当超出这个范围的时候就会新建一个对象
看一个最基本的
例如:
Objet obj = new Object();
变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。
也就是说如果有这样的代码:
Integer a1 = new Integer(1);
Integer a2 = new Integer(1);
Integer a3 = new Integer(1);
Integer a4 = new Integer(1);
Integer a5 = new Integer(1);
假如一个变量需要1k的存储空间一个new Integer也需要1k的存储空间(当然,实际没这么大),那么总共需要10k的存储空间,但是当将1缓存到内存中时,将a1、a2、 a3 、a4、 a5都指向这个1,也就是只需要6k的存储空间,这样就节约了内存。而且新建对象也需要花费时间,所以这样的优化节约了空间和时间。
-128<=i<=127只是JDK的默认范围,当然可以自己将IntegerCache设置大一些。
像字符串常量池和LongCache等都有类似的优化思想。
由于==比较的是引用,所以当数字在-128<=i<=127范围之内时,指向的是同一个地方,返回true;当数字在范围之外时,每次都新建一个对象,指向的是不同的地方,所以返回false。
但是当类型时int时,无论什么数字都返回true。
如果把Java内存简单的区分为堆内存(Heap)和栈内存(Stack),实际中的区域远比这种观点复杂,所指的“栈”就是VM栈中各个帧的本地变量表部分。本地变量表存放了编译期可知的各种标量类型(boolean、byte、char、short、int、float、long、double)、对象引用(不是对象本身,仅仅是一个引用指针)、方法返回地址等。
当
int a1 = 300;
int a2 = 300;
int a3 = 300;
int a4 = 300;
时,并不会创建对象,只会在栈中存放a.b c.d四个变量,和一个数字300。所以无论为1还是300,int时用等于比较都会相等。
另外看如下的代码:
public class test {
public static void main(String args[]){
Integer c1 = 1;
int d1 = 1;
Integer c2 = 300;
int d2 = 300;
System.out.println(c1==d1);
System.out.println(c2==d2);
}
}
输出结果为
true
true
反编译之后可以看到如下代码:
import java.io.PrintStream;
public class test
{
public static void main(String[] paramArrayOfString)
{
Integer localInteger1 = Integer.valueOf(1);
int i = 1;
Integer localInteger2 = Integer.valueOf(300);
int j = 300;
System.out.println(localInteger1.intValue() == i);
System.out.println(localInteger2.intValue() == j);
}
}
也就是Intger和int比较时,会调用Intger.intValue() 方法,所以Intger和int用==比较时,会一直相等。
但是,并不推荐用==比较两个不同的类型。