基础知识:
1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号(==),比较的是他们的值。
2.复合数据类型(类)
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
以上来自http://www.cnblogs.com/zhxhdean/archive/2011/03/25/1995431.html
而这里主要想记录主要是Integar。
基础知识:Ingeter是int的包装类,int的初值为0,Ingeter的初值为null。
case1:int & Integar 128
public static voidmain(String[] args) {
inti =128;
Integer j =128;
Integer k =128;
System.out.println(i == j);
System.out.println(k == j);
}
//result
i == j:true
k == j:false
case2:int & Integar 127
public static voidmain(String[] args) {
inti =127;
Integer j =127;
Integer k =127;
Integer l =newInteger(127);
System.out.println("i == l:"+(i == l));
System.out.println("i == j:"+(i == j));
System.out.println("k == j:"+(k == j));
System.out.println("l == j:"+(l == j));
}
//result
i == l:true
i == j:true
k == j:true
l == j:false
case 1 和case 2 reason:
1. java在编译Integer j = 127的时候,被翻译成-> Integer j = Integer.valueOf(127);所以关键就是看valueOf()函数了。
JDK源码的valueOf函数式这样的:
public staticIntegervalueOf(inti) {
if(i >= IntegerCache.low&& i <= IntegerCache.high)//IntegerCache.high 参考题外话1
returnIntegerCache.cache[i + (-IntegerCache.low)];
return newInteger(i);
}
Integer j = 127在默认情况下,是缓存的最大值。
在缓存范围内,就会直接从缓存中取,就不会new了,return true;
Integer j =128时,因为对象不一样,所以为false。
2. int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比;
3. 无论如何,Integer与new Integer不会相等。不会经历拆箱过程,l的引用指向堆,而j,k指向专门存放他的内存(常量池),他们的内存地址不一样,所以为false
4. 两个都是new出来的,都为false
结论和部分解释来自http://www.cnblogs.com/zhxhdean/archive/2011/03/25/1995431.html
case3:String
public static voidmain(String[] args) {
String i ="127";
String j ="127";
String k =newString("127");
String l = k.intern();
System.out.println(i == j);
System.out.println(k == j);
System.out.println(l == j);
System.out.println(Objects.equals(i, j));
}
//result
i == j:true
k == j:false
l == j:true
Objects.equals(i, j):true
reason:
1. 程序在运行的时候会创建一个字符串缓冲池当使用 i = "127" 这样的表达是创建字符串的时候,程序首先会在这个String缓冲池中寻找相同值的对象,i先被放到了池中,所以在j被创建的时候,程序找到了具有相同值的。
2. k使用了 new 操作符,他明白的告诉程序:"我要一个新的!不要旧的!"于是一个新的”127"Sting对象被创建在内存中。他们的值相同,但是位置不同。
3. java.lang.String的intern()方法"abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方 法没什么用处。但实际上,它做了个小动作:检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会 把"abc"添加到字符串池中,然后再返回它的引用。
解释来自http://www.cnblogs.com/zhxhdean/archive/2011/03/25/1995431.html
//题外话1:
IntegerCache.high可以设置
private static classIntegerCache {
static final intlow= -128;
static final inthigh;
static finalIntegercache[];
static{
// high value may be configured by property
inth =127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if(integerCacheHighPropValue !=null) {
try{
inti =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=newInteger[(high-low) +1];
intj =low;
for(intk =0; k
cache[k] =newInteger(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assertIntegerCache.high>=127;
}
privateIntegerCache() {}
}
//题外话2:
Object a的equals()可以用重写的。
public static booleanequals(Object a, Object b) {
return(a == b) || (a !=null&& a.equals(b));
}