StringBuffer,StringBuilder和String.intern方法

阅读更多

StringBuffer 和StringBuilder区别:

StringBuffer和StringBuilder都继承自抽象类AbstractStringBuilder。

StringBuffer是线程安全的。 StringBuilder是非线程安全的,在单线程使用是,速度更快。

 

String.intern()方法在StringBuffer上的不同表现:以下代码在JDK1.8版本下测试

                System.out.println("*********START TO TEST***********");
		String  a1 = "abcdafds";
		System.out.println("1:" + (a1 == a1.intern()));//true; 直接创建的字符串,保存在常量池中,返回true;
		
		String a2 = new String("abcdafds");
		System.out.println("2:" + (a2 == a2.intern()));//false;通过new创建的字符串,保存在堆中,而该字符串之前已经创建,intern方法指向之前的对象,因此返回false;
		
		String a21 = new String("xyz");
		System.out.println("21:" + (a21 == a21.intern()));//false;通过new创建的字符串,保存在堆中,而该字符串之前不存在,则把该字符串添加进常量池中,并返回指向该字符串的对象,因此返回false;
		
		String a22 = "xyz";
		System.out.println("22:" + (a22 == a21.intern()));//true;直接创建的字符串,该字符串之前在常量池中存在,则直接指向该对象,因此返回true;
		
		String a3 = new StringBuffer("abcdafds").toString();
		System.out.println("3:" + (a3 == a1.intern()));//false; 通过StringBuffer创建的字符串,保存在堆中,而由于常量池中已有该字符串,则返回false;
		
		String a31 = new StringBuffer("xab").toString();
		System.out.println("4:" + (a31 == a31.intern()));//false;通过StringBuffer创建的字符串,保存在堆中,则返回false;

		String a4 = new StringBuffer("abcdafds").append("").toString();
		System.out.println("5:" + (a4 == a1.intern()));//false;通过StringBuffer创建,并包含一个append的字符串,如果该完整字符串之前已经创建 ,则保存在堆中,而由于常量池中已有该字符串,则返回false;
		
		String a5 = new StringBuffer("abcd").append("afds").toString();
		System.out.println("6:" + (a5 == a5.intern()));//false;通过StringBuffer创建,并包含一个append的字符串,如果该完整字符串之前已经创建 ,则保存在堆中,而由于常量池中已有该字符串,则返回false;
		
		String a6 = new StringBuffer("aaxx").append("bbfda").toString();
		System.out.println("7:" + (a6 == a6.intern()));//true;通过StringBuffer创建,并包含一个append的字符串,如果该完整字符串之前不存在,则保存在堆中,调用intern方法后,常量池中添加一个指向堆中对象的引用,因此返回true;
		
		String a62 = new StringBuffer("ayyx").append("").toString();
		System.out.println("8:" + (a62 == a62.intern()));//false;通过StringBuffer创建,并包含一个append为""的字符串,则保存在堆中,调用intern方法后,把该字符串添加进常量池中,因此返回false;
		
		String a63 = new StringBuffer("ayx").append("bz").append("xdsd").toString();
		System.out.println("9:" + (a63 == a63.intern()));//true;通过StringBuffer创建,并包含二个append的字符串,如果该完整字符串之前不存在,则保存在堆中,调用intern方法后,常量池中添加一个指向堆中对象的引用,则返回true;
		
		String a64 = new StringBuffer("ayxbzxdsd").toString();
		System.out.println("10:" + (a64 == a64.intern()));//false;通过StringBuffer创建,保存在堆中,因为该字符串的引用已经存在,因此返回false;
		
		String a65 = new StringBuffer("ayxb").append("zxdsd").toString();
		System.out.println("11:" + (a65 == a65.intern()));//false;通过StringBuffer创建,保存在堆中,因为该字符串的引用已经存在,则返回false;
		
		System.out.println("112:" + (a64 == a65));
		
		String a66 = new StringBuffer("ayb").append("xdsd").toString();
		System.out.println("12:" + (a66 == a66.intern()));//true;通过StringBuffer创建,如果该完整字符串之前不存在,则保存在堆中,调用intern方法后,常量池中添加一个指向堆中对象的引用,则返回true;
		
		String a67 = new StringBuffer("ay").append("bxdsd").toString();
		System.out.println("13:" + (a67 == a67.intern()));//false;通过StringBuffer创建,如果在堆中,因为该字符串的引用已经存在,则返回false;
		
		String a68 = new StringBuffer("ayb").append("xdsd").toString();
		System.out.println("14:" + (a68 == a68.intern()));//false;通过StringBuffer创建,保存在堆中,因为该字符串的引用已经存在,则返回false;
		
		String a7 = new StringBuffer("ancddaf").toString();
		System.out.println("15:" + (a7 == a7.intern()));//false;通过StringBuffer创建,不包含append的字符串,则保存在堆中,调用intern方法后,把该字符串添加进常量池中,返回false;
		
		String a8 = new StringBuffer("ancddaf").append("").toString();
		System.out.println("ancddaf" == a8.intern());//true,常量池中已包含该字符串,则返回true;

 

 

针对StringBuffer的特殊表现,总结如下:

1,当使用StringBuffer创建字符串时,如果不包含append方法,或者包含的append方法字符串为"", 则该StringBuffer对象与String对象的表现一致,即: StringBuffer对象保存在堆中,并且在常量池中复制一份该字符串,与堆中的字符串不是同一对象。

2,当使用StringBuffer创建字符串,并且包含一个或多个append方法时,即:StringBuffer对象保存在堆中,在常量池中保存一份对该对象的引用。因此调用intern方法时,发现指向的是同一个对象。

 

你可能感兴趣的:(java,string,StringBuffer,String.intern)