一、equal和“==”的区别
(1)equal的作用是比较两个独立对象的内容是否相同。换句话说,就是去比较两个对象的值。
Integer i1 = 128;
Integer i2 = 128;
System.out.println(i1==i2);//false
System.out.println(i1.equals(i2));//true
i1,i2是两个Interage对象,因此equal比较的是i1,i2的值128。
(这里特意将Interage的值设置为128,当为-128—127时会出现都为true的情况,原因后面解释)
(2)、“==”比较的是那个变量的值是否相等。
在上例的代码中,i1==i2
结果为:false
。原因在于i1
存储的值是指向Interage对象128
的内存地址,由于那个对象的内存中的地址不同,因此i1,i2
中存储的值(内存地址值不同),因此i1==i2
结果为:false
。
如果一个变量指向的数据是对象类型,这时候就涉及到两块内存,对象本身占用一块内存,变量也占用一块内存。如:
Object obj = new Object();
变量obj
是一个内存,对象new Object
是一个内存。此时,obj
内存中储存的是对象的内存首地址。(obj这里的作用像C语言中的指针。)
因此要比较两个对象是否是同一个需要使用“==”
。
二,基本数据类型的缓存池
(1)、基本类型对应的缓冲池如下:
- boolean :true and false
- all byte values
- short : -128 —127
- int : -128 — 127
- char :\u0000 to \u007F
- Interage默认为:-128到127
在使用这些基本类型对应的包装类型时,如果该数值范围在缓冲池范围内,就可以直接使用缓冲池中的对象。
在 jdk 1.8 所有的数值类缓冲池中,Integer 的缓冲池 IntegerCache 很特殊,这个缓冲池的下界是 - 128,上界默认是 127,但是这个上界是可调的,在启动 jvm 的时候,通过AutoBoxCacheMax=<size>
来指定这个缓冲池的大小,该选项在 JVM 初始化的时候会设定一个名为java.lang.IntegerCache.high
系统属性,然后 IntegerCache 初始化的时候就会读取该系统属性来决定上界。
(2)、缓冲池的作用
在使用基本类型对应包装类型时,当数据的范围在缓冲池的范围,就会使用缓冲池中的已有的对象。拿上面的例子中的Interage
举例。
Integer a = 127;
Integer b = 127;
System.out.println(a==b);//(true)调用了缓存池的(范围:-128—127),当用这个时,是同一个对象
System.out.println(a.equals(b));//true
在上面的例子中,提到i1,i2
的大小设置问题,就是由于Interage存储着一个默认大小为-128—127的缓冲池。当在这个范围内时,就会使用同一个对象。
三、String中类似于缓冲池的String Pool
String s1 = "str";
String s2 = "str";
System.out.println(s1 == s2);//true
System.out.println(s1.equals(s2));//true
在使用String时,当创建了一个String对象时,该对象就会被放到存储的堆中,当另外一个String对象被创建时,会先到String Pool中查看,是否存在,如果存在就直接使用,因此为了同一个对象。在代码中表现为s1和s2中存储的值都是同一个String对象的首地址。
String pool (String intern pool) is a special storage area in Method Area. When a string is created and if the string already exists in the pool, the reference of the existing string will be returned, instead of creating a new object.
参考:CS-Notes