1. 引言
在学习Java_String类的过程中,判断字符串相等的==与equals实际运行结果不同,于是想查清为何,以及如何Java内存如何运作。特此记录提醒自己。
2. ==与equals
- 对于基本数据类型,不需要引用的情况:包括boolean,byte,short,int,long,float,double等,彼此之间的判断可直接用==,为值的比较
- 对于引用数据类型,如String类等,对于此类比较时,==为比较两者的内存地址。
- equals来说,对于引用类型,默认也是比较其内存地址,但是大多经过重写,在lang包中一般将其重写为比较两者的值。
3. 示例代码
public class StringClassLearning {public static void main(String[] args) {//1.编译期间完成字符串拼接String str1 = "hello"+" JiangLian";String str2 = "hello JiangLian";System.out.println(str1 == str2);String str3 = "hello";String str4 = " JiangLian";String str5 = str3+str4;System.out.println("HashCode打印内存地址方法");/** str1: -669484201* str2: -669484201* str5: -669484201*/System.out.println("str1: "+str1.hashCode());System.out.println("str2: "+str2.hashCode());System.out.println("str5: "+str5.hashCode());System.out.println("identityHashcode打印内存地址方法");/** str1: 305808283* str2: 305808283* str5: 2111991224*/System.out.println(System.identityHashCode(str1));System.out.println(System.identityHashCode(str2));System.out.print(str5+"内存地址为");System.out.println(System.identityHashCode(str5));System.out.println(str2 == "hello JiangLian");System.out.println(str5 == "hello JiangLian");}}
代码所示:
- str1与str2相等是由于编译器的遇到字符串常量之间的拼接时,做出优化,即在编译期间就会完成字符串的拼接,因此两者在运行时,引用类型数据指向的常量是一个。因此两者==为true
- str5与str2不相等,执行过程为:内存执行过程
https://blog.csdn.net/hl_java/article/details/104497737
- 栈中开辟内存存放引用str3,str3指向常量池中的“hello”
- 栈中开辟内存存放引用str4,str4指向常量池中的“ JiangLian”
- 栈中开辟内存存放引用str5
- str3 + str4通过StringBuilder的最后一步toString()方法还原一个新的String对象"hello JiangLian",因此堆中开辟一块空间存放此对象。对应的内存地址变化
- 引用类型str5指向改新开辟的内存空间
- 内存地址获取方法:
- hashcode获取地址,不是引用的真实内存地址,是经过String类重写过的hashcode,利用该方法获取地址,三者的内存地址相同,
- 通过System.identityHashCode(Object)判断三者的内存,确认==不同