下面是我看别人博客和java API总结的
首先得明确一个概念就是:
== 的用法 ==比较对象在内存中的地址是否相等。如是是两个基本数据类型变量的比较则比较的是这两个变量值是否相等,但是这里要注意,对于Integer对象来说,其能存储的范围为(-128~127),超过范围则存储到堆内存中。,若是比较两个引用型变量则比较的是对象存储的地址是否相同,即栈中的内容是否相同,(对象存储在堆中,而对象的引用是存储在栈中)(这些必须先明确,否则后面的源码分析就不好理解)
equals的用法 equals比较的是对象之间内容是否相同。
先看java中的Object抽象类对equals()方法的定义:
public boolean equals(Object obj) {
return (this == obj);
}
这是对传入的对象进行== 比较,因为是引用类型,所以比较的是地址。所以在Object类中的equals是比较两个对象的应用地址是否相同(后面我们将要讲到的String类型的equals()方法就不是这样了,因为它重写了equals()方法!)
我们看String类中对equals()方法的定义:
public boolean equals(Object anObject) { if (this == anObject) { // 如果是相同的对象 return true; } if (anObject instanceof String) { //不是相同对象就比较内容 String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }
所以对String的equals()方法是比较当前字符串与传进来的字符串是否相同
Java常量池
Java的8种基本类型(Byte, Short, Integer, Long, Character, Boolean, Float, Double), 除Float和Double以外, 其它六种都实现了常量池, 但是它们只在大于等于-128并且小于等于127时才使用常量池。
由如下例子可以看出:
import org.junit.Test; public class JUnitTest { @Test public void test1() { Integer a = 127; Integer b = 127; System.out.println("等于127:"); System.out.println(a == b); //true System.out.println("*****************"); a = 128; b = 128; System.out.println("等于128:"); System.out.println(a == b); //false System.out.println("*****************"); a = -128; b = -128; System.out.println("等于-128:"); System.out.println(a == b); //true System.out.println("*****************"); a = -129; b = -129; System.out.println("等于-129:"); System.out.println(a == b); //false System.out.println("*****************"); // 测试Boolean System.out.println("测试Boolean"); Boolean booleanA = false; Boolean booleanB = false; System.out.println(booleanA==booleanB); //true System.out.println("*****************"); boolean booleanC = false; boolean booleanD = false; System.out.println(booleanC==booleanD); //true System.out.println("*****************"); // 测试Float System.out.println("测试Float"); float floatA = 1.4f; float floatB = 1.4f; System.out.println(floatA==floatB); //true System.out.println("*****************"); Float floatC = 12.3f; Float floatD = 12.3f; System.out.println(floatC==floatD); //false System.out.println("*****************"); // 测试Float System.out.println("测试Character"); Character charA = 'A'; Character charB = 'A'; System.out.println(charA==charB); //true System.out.println("*****************"); char charC = 'B'; char charD = 'B'; System.out.println(charC==charD); //true System.out.println("*****************"); } }
当我们给Integer赋值时,实际上调用了Integer.valueOf(int)方法,查看源码,其实现如下:
public static Integer valueOf(int i) { if(i >= -128 && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; else return new Integer(i); }
而IntegerCache实现如下:
private static class IntegerCache { static final int high; static final Integer cache[]; static { final int low = -128; // high value may be configured by property int h = 127; if (integerCacheHighPropValue != null) { // Use Long.decode here to avoid invoking methods that // require Integer's autoboxing cache to be initialized int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} }
注意cache数组是静态的。