String主要有这么两种赋值方式:
一、类似普通对象,通过new创建字符串对象。String str = new String("abc");
二、类似原型那样直接赋值。如String str = "abc";
这两种赋值方式有什么不同,估计很多人也多少有些了解?下面我们主要围绕几个问题展开:
1、为什么String可以不用new就可以创建对象?
2、这两种赋值方式有什么不同?
一、
打开了String.class,有这么一段介绍:
通过上面的介绍,我们可以清楚,直接赋值的话,赋值方式二,是通过编译器在起作用,当你对"abc"没有通过new创建时,他会自动默认给你调用构造函数new String(char value[]).
所以问题一也就有答案了。不显式调用String的构造函数(通过new叫显式调用),其实JDK编译器会自动给你加上。
但也并不全然,显式和隐式之间也有差别的。
二、
隐式:String password="ok";
利用到了字符串缓冲池,也就是说如果缓冲池中已经存在了相同的字符串,就不会产生新的对象,而直接返回缓冲池中的字符串对象的引用。
如:
String a = "ok"; // 新建了一个String对象
String b = "ok"; // 从缓冲池找
String c = new String("ok"); // 新建一个String对象
String d = new String("ok"); // 不从缓冲池找,新建一个
System.out.println(a==b);//将输出"true";因为两个变量指向同一个对象。
System.out.println(c==d);//将输出"flase";因为两个变量不指向同一个对象。虽然值相同,只有用c.equals(d)才能返回true.
用Eclipse Debug了一下,查看了b和c的组成,外部结构式一样的,但是内存地址没法查看。
由图可以看出,b和c的value是一样的,而equals方法正是比较value的每个字符得出结果的。而=是比较对象的内存地址得出的(引用的内容来自同一个地方):
下面是String的equals的源代码: