java中==和equals方法有什么区别详解
java开放中,经常遇到判断。你在==和equals之间如何选择?
==和equals区别
6句话简单总结==和equals的区别:
== 是判断两个变量或实例是不是指向同一个内存空间
== 是指对内存地址进行比较
== 是引用是否相同
equals() 是判断两个变量或实例所指向的内存空间的值是不是相同
equals() 是对字符串的内容进行比较
equals() 指的是值是否相同
栈和堆
首先来简单了解下栈和堆
栈:存的是基本类型和对象的引用(引用、内容地址)
堆:存的是对象和数组(值、内容)
8种基本类型
java的8种基本数据类型
基本数据类型是存于栈中包括:byte,short,char,int,long,float,double,boolean
String数据类型是一种特殊数据类型,既可以用基本数据类型格式来创建,也可以用普通基本类型来创建。JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。
实际运用
好了,简单了解了以上这些那些,可能你已经知道怎么用,在哪里用==和equals了。
例子1
首先来看一组常见的==使用。基本类型栈引用相同。
//基本数据类型用==比较 int a1 = 8; int b1 = 8; System.out.println("a1 == b1:" + (a1 == b1)); //a1 == b1:true
例子2
再来看一组特殊的比较字符串string。
1、与基本类型初始化语法一样的写法是存于常量词中,常量池中的对象可以共享。
//编译a1后再编译b2,常量池已有127,所以划分相同引用,内存地址是一样的 String a2 = "8"; String b2 = "8"; System.out.println("a2 == a2:" + (a2 == b2)); //a2 == a2:true
2、直接使用 new String()来创建。
//new直接开辟内存空间,a3和b3在栈中内存地址(引用)不一样 String a3 = new String("8"); String b3 = new String("8"); //引用比较 System.out.println("a3 == b3:" + (a3 == b3)); //a3 == b3:false //值比较 System.out.println("a3 equals b3:" + (a3.equals(b3))); //a3 equals b3:true
例子3
接下来再看下Integer比较那些事
//在值-128到127,==比较引用都是相同的。 Integer n1 = 127; Integer m1 = 127; System.out.println("n1 == m1:" + (n1 == m1)); //n1 == m1:true
接着看
Integer n2 = 128; Integer m2 = 128; System.out.println("n2 == m2:" + (n2 == m2)); //n2 == m2:false System.out.println("n2 equals m2:" + (n2.equals(m2))); //n2 equals m2:true
也许你有疑问:为何对象n1==m2是相等呢?而n2==m2又不相等呢?你在开发的那些年有没有写错呢?写错就大祸了,呵呵。
原来:
Integer把-128到127(可调)的整数都提前实例化了,存在Integer的缓存类IntegerCache中,用到在那范围的数值都是同一引用,不会再去实例化了。如果不是该范围直接new Integer()去创建新的实例。
来看看Integer类源代码片段
... private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } 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() {} } /** * Returns an {@code Integer} instance representing the specified * {@code int} value. If a new {@code Integer} instance is not * required, this method should generally be used in preference to * the constructor {@link #Integer(int)}, as this method is likely * to yield significantly better space and time performance by * caching frequently requested values. * * This method will always cache values in the range -128 to 127, * inclusive, and may cache other values outside of this range. * * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */ public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } ...
由 valueOf(int i) 方法可见范围只有 -128 ~ 127 值。超出该范围则直接 return new Integer(i),所以对象的引用不再相同,因此不在那范围的值用==是不相等的。
至此完毕。
原创文章,转载请注明出处:https://www.weizhixi.com/article/26.html