==是在基本类型里比较值的大小,在引用类型里是比较数据指向的地址是否相同。
八种基本类型:byte,short,int,long,float,double,boolean,char.
八种基本类型之外的是引用类型,String就是引用类型。
String拼接有两种形式:
1.常量拼接:
String a = "a";
String b ="bc";
String c ="a"+"bc";
String d="abc";
因为是常量,所以会在java常量池中存放一个a和一个bc,在拼接的时候因为没有abc字符串,但常量池中有a,bc会直接将已有的a和bc拼接起来也放在常量池中。再给d赋值abc时常量池已经有直接用就行。用==比较c和d因为用的都是常量池里的abc所以返回的结果是true。
2.变量拼接
String A="a";
String B="bc";
String c=A+B;
String d="abc";
String str=new String("abc");
str是个对象实例会在栈中开辟一块空间,使用new String会在堆中开辟一块空间。对象实例在栈中开辟空间、new String在堆中开辟空间,但里面的字符串abc会存放在常量池中,栈中的str实例会指向堆中new开辟出那块空间的地址,而对象实例str想用abc这个字符串就会在它的堆中指向常量池中abc的地址,放在常量池的目的是:别的对象想调用abc时就不用再开辟新的空间从而造成内存空间的浪费。其他对象也是同样的方法存放字符串。
jvm内存图如下:
c=A+B就是用变量拼接,只要有一个变量就是变量拼接,拼接的原理是StringBuilder,
StringBuilder c=new StringBuilder("");
c.append("a").append("bc").toString();
也就是在堆中新开辟出一个空间在空间中进行拼接abc(abc在堆中放了一个)并把abc放常量池中,所以用==比较c和d的值时c的abc是在堆中的而d的abc是在常量池中的所以返回的的结果是false。
String e=c.intern();
如果用了以上方法再比较e==d返回的结果就是true了,因为实例e会把地址指向常量池中。