String类创建方式:
1、双引号型
2、new型
package ecut.strings; public class StringTest1 { public static void main(String[] args) { // 所有的 "" 包起来的 字符串 字面值一律放在 字符串常量池中 //去字符串常量池池寻找相同内容的字符串,如果存在就直接拿出来应用,如果不存在则创建一个新的字符串放在常量池中。 String s = "hello,ecut" ; System.out.println( System.identityHashCode( s ) ); //通过 new关键字创建 String 对象,每次调用都会创建一个新的对象。 String x = new String( "hello,ecut" ); System.out.println( System.identityHashCode( x ) ); System.out.println( s == x ); // 返回字符串对象的规范化表示形式 // 如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。 // 否则,将此 String 对象添加到池中,并返回此 String 对象的引用(加入到池中以后的那个串的地址) String str = x.intern(); System.out.println( System.identityHashCode( str ) ); System.out.println( str == s ); } }
运行结果如下:
366712642 1829164700 false 366712642 true
从结果可以看出s和x的地址是不相等的,是因为String s = "hello,ecut", 首先在常量池中查找是否存在内容为"hello,ecut"字符串对象,如果不存在则在常量池中创建"hello,ecut",并让s引用该对象(12345),如果存在则直接让s引用该对象,而new String( "hello,ecut" )时会在堆中创建一个对象ABCDE,并由栈中x引用堆中的ABCDE对象,然后在在字符串常量池中查看,是否存在内容为"hello,ecut"字符串对象,若存在,则将new出来的字符串对象与字符串常量池中的对象(12345)联系起来若不存在,则在字符串常量池中创建一个内容为"hello,ecut"的字符串对象,并将堆中的对象与之联系起来。x.intern()方法则是如果池已经包含一个等于此 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串,否则,将此 String 对象添加到池中,并返回此 String 对象的引用(加入到池中以后的那个串的地址)。因此str和s地址相同。
==比较的是2个对象的地址,而equals比较的是2个对象的内容。
栈:运行时的单位,存放基本类型的变量数据和对象的引用,栈解决程序的运行问题,即程序如何执行,或者说如何处理数据。
堆:存储的单位,用于存放所以的JAVA对象,堆解决的是数据存储的问题,即数据怎么放、放在哪儿。
常量池:存放字符串常量和基本类型常量(public static final)
字符串联的两种方式:
package ecut.strings; /** * 当 字符串 变量 参与 串联 操作时 * 是通过 StringBuilder ( 或 StringBuffer ) 类及其 append 方法实现的 */ public class StringTest5 { public static void main(String[] args) { String a = "abc" ; String b = "xyz"; String d = "abcxyz" ; // 两个字符串字面值 通过 + 串联,直接在 池中完成 String c = "abc" + "xyz" ; // + 是 "串联" 作用 System.out.println( c == d ); System.out.println( "~~~~~~~~~~~~~~" ); // 字符串串联是通过 StringBuilder ( 或 StringBuffer ) 类及其 append 方法实现的 // 1、StringBuilder sb = new StringBuilder( a ); // 2、sb.append( b ) ; // 3、sb.toString() ---> new String( chars ) String e = a + b ; System.out.println( e == c ); System.out.println( e == d ); String f = e.intern(); System.out.println( f == d ); } }
运行结果如下:
true ~~~~~~~~~~~~~~ false false true