String 总结

申明:

1. 首先String不属于8种基本数据类型,String是一个对象。 因为对象的默认值是null,所以String

的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。 

2. new String()new String("")都是申明一个新的空字符串,是空串不是null
3. String str="kvill"; 与 String str=new String ("kvill");的区别:

 

在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。 

常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。 
1: 

 

String s0="kvill"; 
String s1="kvill"; 
String s2="kv" + "ill"; 

System.out.println( s0==s1 ); 
System.out.println( s0==s2 );

结果为: 

true 
true


首先,我们要知结果为道Java会确保一个字符串常量只有一个拷贝。 


因为例子中的s0s1中的"kvill"都是字符串常量,它们在编译期就被确定了,所以s0==s1true;而"kv"和"ill"也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中"kvill"的一个引用。 所以我们得出s0==s1==s2; 

注:用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。在运行时创建的字符串具有独立的内存地址,所以不引用自同一String对象
2: 

String s0="kvill"; 
String s1=new String("kvill"); 
String s2="kv" + new String("ill"); 

System.out.println( s0==s1 );
System.out.println( s0==s2 );
System.out.println( s1==s2 );

结果为:

false 
false 
false

 

2s0还是常量池中"kvill"的应用,s1因为无法在编译期确定,所以是运行时创建的新对象"kvill"的引用,s2因为有后半部分new String("ill")所以也无法在编译期确定,所以也是一个新创建对象"kvill"的应用;明白了这些也就知道为何得出此结果了。 

4、String.intern(): 
存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。Stringintern()方法就是扩充常量池的一个方法;当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

3: 

String s0= "kvill"; 

String s1=new String("kvill"); 
String s2=new String("kvill"); 

System.out.println( s0==s1 ); 
System.out.println( "**********" ); 

s1.intern(); 
s2=s2.intern(); //把常量池中"kvill"的引用赋给s2 

System.out.println( s0==s1); 
System.out.println( s0==s1.intern() ); 
System.out.println( s0==s2 );


结果为: 

false 
********** 
false //虽然执行了s1.intern(),但它的返回值没有赋给s1 
true //说明s1.intern()返回的是常量池中"kvill"的引用 
true


4: 

String s1=new String("kvill"); 
String s2=s1.intern(); //s1 检查常量池 发现没有 就拷贝自己的字符串进去 ,s2 引用该字符串常量池的地址

System.out.println( s1==s1.intern());

System.out.println( s1+" "+s2 );
System.out.println( s2==s1.intern());


结果: 

false 
kvill kvill 
true


在这个类中我们没有声名一个"kvill"常量,所以常量池中一开始是没有"kvill"的,当我们调用s1.intern()后就在常量池中新添加了一个"kvill"常量,原来不在常量池中的"kvill"仍然存在。
s1==s1.intern()false说明原来的"kvill"仍然存在; 
s2现在为常量池中"kvill"的地址,所以有s2==s1.intern()true。 

5、关于equals()==: 
equals简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。 对于字符串比较,一定要切记使用equals,勿用==.

 

StringStringBufferStringBuilder区别

1、三者在执行速度方面的比较:StringBuilder >  StringBuffer  >  String

2、(StringBufferStringBuilder)在做字符串变动时将继续使用原来的内存空间,不会重新分配内存。而String的长度或内容一旦变动,JVM将分配新的内存空间。

 

String <StringBufferStringBuilder)的原因

    String 字符串常量

    StringBuffer 字符串变量

    StringBuilder 字符串变量

从上面的名字可以看到,String"字符串常量",也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问,比如这段代码:

String s = "abcd";
s = s+1;
System.out.print(s);// result : abcd1

我们明明就是改变了String型的变量s的,为什么说是没有改变呢其实这是一种欺骗,JVM是这样解析这段代码的:首先创建对象s,赋予一个abcd,然后再创建一个新的对象s用来执行第二行代码,也就是说我们之前对象s并没有变化,所以我们说String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多底。

StringBufferStringBuilder就不一样了,他们是字符串变量,是可改变的对象,每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些额外的对象进行操作了,效率自然提升。

 

2一个特殊的例子:

String str = "This is only a" + " simple" + " test";
StringBuffer builder = new StringBuilder("This is only a").append(" simple").append(" test");

你会很惊讶的发现,生成str对象的速度简直太快了,而这个时候StringBuilder居然速度上根本一点都不占优势。其实这是JVM的一个把戏,实际上:

    String str = "This is only a" + " simple" + "test";

其实就是:

    String str = "This is only a simple test";

  所以不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的String对象的话,速度就没那么快了,譬如:

    String str2 = "This is only a";

    String str3 = " simple";

    String str4 = " test";

    String str1 = str2 +str3 + str4;

    这时候JVM会规规矩矩的按照原来的方式去做。

3StringBuilder与 StringBuffer

    StringBuilder:线程非安全的

    StringBuffer:线程安全的

当我们在字符串缓冲去被多个线程使用是,JVM不能保证StringBuilder的操作是安全的,虽然他的速度最快,但是可以保证StringBuffer是可以正确操作的。当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用StringBuilder而不用StringBuffer的,就是速度的原因。

 

对于三者使用的总结: 

1、如果要操作少量的数据 = String

   2、单线程操作字符串缓冲区 下操作大量数据 = StringBuilder

   3、多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

posted @ 2012-11-01 19:19  滴水瓦  阅读(247)  评论(0编辑  收藏  举报