String s1="abc"与String s2=new String("abc")分别的构建过程:
首先说下常量区:常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。
String s1="abc"会首先在String池(String pool 它是存在于常量池中的)寻找是否有一个"abc"对象已经存在,如果存在则直接把那个对象的引用赋给S1,如果没有则在String池中创建一个新的"abc"类。
String s2=new String("abc")也会首先在String池里寻找是否由一个"abc"对象已经存在,如果存在则把那个对象COPY一份到Heap中,如果没有则在常量区创建一个"abc"对象,再把它COPY一份到Heap中。这个结论从如下jdk中的定义可以得到应正。
String
public String(String original)
-
初始化一个新创建的
String
对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。由于 String 是不可变的,所以无需使用此构造方法,除非需要original
的显式副本。-
参数:
-
original
- 一个String
。
-
例程:
public class test{
public static void main(String args[]){
String s=new String("abc"); //这句先在String池中创建了一个"abc"对象,再拷贝个相同的对象到
堆中返回堆中这个对象的引用。即创建了两个对象。
String ss="abc"; //不会产生新的对象,返回"abc"对象在String池中的那个对象的引用。
String sss=new String("abc"); //会在堆中产生一个新的"abc"对象。
}
}
String与StringBuffer的区别:
String类是不可变的,而StringBuffer是可以的。这里的可变并不是说String的句柄不可变,如:String ss="abc";ss(句柄是可以再去指向其它的类)。而存储空间中的那个类是不能改变的,而StringBuffer则可以改变,如StringBuffer ss="abc";ss.append("dfg");即ss这个引用所指的对象发生了改变。
String对象之间的比较:
对于引用对象来说,==永远比较的是内存地址,String之间要比较字符串值是否相等要用str1.equals(str2)。
intern()的用法:
对一个String对象调用intern()方法后,如果该对象是在String池中那么返回的是此对象的引用,如果此对象不在String池中则先检查String池中是否有和该对象相同的对象,如果有则返回String池中和该对象相同的对象的引用,如果没有则将该对象加入String池中,并返回加入String池中的对象的引用。
以上所说从jdk中也可以得到相应应正。
intern
public String intern()
-
返回字符串对象的规范化表示形式。
一个初始为空的字符串池,它由类
String
私有地维护。当调用 intern 方法时,如果池已经包含一个等于此
String
对象的字符串(用equals(Object)
方法确定),则返回池中的字符串。否则,将此String
对象添加到池中,并返回此String
对象的引用。它遵循以下规则:对于任意两个字符串
s
和t
,当且仅当s.equals(t)
为true
时,s.intern() == t.intern()
才为true
。 -
-
-
返回:
- 一个字符串,内容与此字符串相同,但一定取自具有唯一字符串的池。