例1:
String str1 = "java";
String str2 = "java";
System.out.print(str1==str2);
基本数据类型之间应用==,比较的是他们的数值。
复合数据类型(类)之间应用==,比较的是他们在内存中的存放地址。
这里==比较的是引用即比较的是物理地址。原本结果应该是false,但是结果是true,原因是第一个String对象java被放进了常量池中,当再出现java字符串的时候,JVM会将str2也指向之前就有的java字符串。
.............................................................................................................................................................
常量池的作用:(https://www.jianshu.com/p/c7f47de2ee80)
常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。
例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。
(1)节省内存空间:常量池中所有相同的字符串常量被合并,只占用一个空间。
(2)节省运行时间:比较字符串时,==比equals()快。对于两个引用变量,只用==判断引用是否相等,也就可以判断实际值是否相等。
..............................................................................................................................................................
------------------------------------------------------------------------------------------------------------
例2:
String str1 = new String("java");
String str2 = new String("java");
System.out.print(str1==str2);
new的作用是会让JVM在堆内存中开辟一个String空间,保存java字符串,str1和str2的值虽然都是java,但是一共new了两次,开辟了不同的对内存空间,地址不同,所以结果是false。
------------------------------------------------------------------------------------------------------------
例3:
String str1 = "java";
String str2 = "blog";
String s = str1+str2;
System.out.print(s=="javablog");
结果是false,原因是在编译阶段JVM会把str1 和 str2放到常量池中,而str1+str2的结果会存在堆里面,s的引用指向堆内存,而javablog是一个常量,s的引用根本不会指向这个常量。
------------------------------------------------------------------------------------------------------------
例4:
String str1 = "java";
String str2 = new String("java");
System.out.print(str1.equals(str2));
无论在常量池还是堆中的对象,用equals()方法比较的就是内容。
------------------------------------------------------------------------------------------------------------