现在的位置: 首页 > 综合 > 正文

Java深入学习(1)——漫话String

2014年08月20日 ⁄ 综合 ⁄ 共 2930字 ⁄ 字号 评论关闭

     Java中String类继承自Object类,并实现了Serializable, Comparable, CharSequence接口。Java中一切字符常量如:“abc”都是String类的一个实例对象。可以说String类是Java开发中使用最为频繁的类之一,下面将围绕String类的一些常见问题进行一个梳理总结,一方面作为自己学习的一个书面总结,方便以后查漏补缺;另一方面写成博文的方式可以借鉴广大网友的渊博知识形成交流互动,更好的更全面的学习Java语言。(注:由于个人水平有限,文中难免有失误与不周到之处,恳请各位网友赐教、斧正!)

一:String的不变性(immutable)

    String对象的不变性是指:一旦对象在内存中创建,其对象的值是保持不变的,即使是对String对象进行任何操作(对已有String对象操作不改变其本身的值,而是生成了新的String对象)。Java中提供了另外的StringBuffer类来实现可变的字符串对象,关于两者的区别于应用场合将在下面详细介绍。

Java中为什么要将String设计成immutable?

      1.  Java中的String对象存储在内存堆中的一个字符驻留池中。当创建一个新的String对象时,如果该字符串已经存在于驻留池,那么就返回这个字符串的引用,否则创建一个新的字符串对象并返回其引用。考虑到如果两个String对象引用于内存中同一个字符串对象,如果String是可变的,那么改变其中一个引用的值将会导致另一个引用对象的值出现错误。所以,Java将String设计成不可变的,一个引用对象的改变时生成一个新的String对象,原来同样引用该对象的值不会发生改变。

      2.String对象的哈希码值经常在Java中用到,如HashMap。我们再将String对象作为HashMap的关键字(key)时,如果String是不可变的,那么我们可以将其hashcode值只计算一次就缓存起来提高运行效率而不用考虑String对象的改变而每次都去计算一次hashcode值。

      3.String在Java编程中被广泛的应用为类的参数,考虑到如果String是mutable,那么在一些网络连接和文件读写中将会带来一些不可意料的安全威胁。因此Java将String设计成不可变的。

二:String常用方法说明

1.   如何比较两个Strings “==”or  eauqls()?

		String str1 = "hello";
		String str2 = "hello";
		if (str1 == str2)
			System.out.println("--true--");// 结果为真
		else
			System.out.println("--false--");

		if (str1.equals(str2))
			System.out.println("--true--");// 结果为真
		else
			System.out.println("--false--");

    当str1和str2指向内存中同一个String对象时,“==”和equals()方法都返回真。

		String str1 = "hello";
		String str2 = new String("hello");
		if (str1 == str2)
			System.out.println("--true--");// 结果为假
		else
			System.out.println("--false--");

		if (str1.equals(str2))
			System.out.println("--true--");// 结果为真
		else
			System.out.println("--false--");

str1和str2指向内存中不同的String对象,但值相同时,“==”返回假,equals()返回真。由此可见“==”是比较两个String的引用,即两者是否是同一对象;而equals()比较的是两者的值是否相等。如果非要用"=="比较两个对象的内容的话需先调用intern()方法对于第一种定义,jvm会马上在heap中创建一个String对象,然后将该对象的引用返回给用户。对于第二种,jvm首先会在内部维护的strings
pool中通过String的 equels 方法查找是对象池中是否存放有该String对象,如果有,则返回已有的String对象给用户,而不会在heap中重新创建一个新的String对象;如果对象池中没有该String对象,jvm则在heap中创建新的String对象,将其引用返回给用户,同时将该引用添加至Strings pool中。而调用intern()方法就相当于第二种定义方式,该方法会确保Strings pool中存在该对象的引用。所以对于两个Strings对象:a和b来说要是a.intern()==b.intern()成立的必要条件是a.equals(b)为真。

		String str1 = "hello";
		String str2 = new String("hello");
		if (str1.intern() == str2.intern())
			System.out.println("--true--");// 结果为真
		else
			System.out.println("--false--");

三:String,StringBuffer以及StringBuilder的比较

    前面提到过String具有不可变(immutable)的性质,而Java提供了两个mutable的String类:StringBuffer和StringBuilder。那么这两个之间有什么区别了,他们分别应用于什么样的场合了?

      StringBuffer:其显著的特点是其具有线程安全的特性,在多线程处理的场合我们一般选择StringBuffer作为可变String处理的理想对象。StringBuffer类主要使用的两个方法分别是:append()和insert(),其作用分别是在现有字符串对象的末尾附加上新的字符串和在制定位置插入新的字符串来改变原字符串对象。由于StringBuffer是线程安全的,对其对象的任何操作,操作方法本身具有synchronization的过程所以其运行效率不高。

      StringBuilder:与StringBuffer相同,它们都是可变(mutable)Strings并且具有类似的Api接口方法,其最大的区别是其不具有线程安全的特性。在Java的官方文档中强调了StringBuilder的应用场合是:在单线程的用用场合下,或者是不需要考虑线程同步的时候推荐使用StringBuilder代替StringBuffer,因为其通常具有更高的运行效率。


参考文章:

http://www.programcreek.com/2009/02/diagram-to-show-java-strings-immutability/  点击打开链接

http://www.programcreek.com/2013/09/top-10-faqs-of-java-strings/  点击打开链接



 

抱歉!评论已关闭.