三、字W串对象的创?׃字符串对象的大量使用[它是一个对象,一般而言对象L在heap分配内存]QJava中ؓ了节省内存空间和q行旉[如比较字W串Ӟ==比equals()快]Q在~译阶段把所有的字符串文字放C个文字池[pool of literal strings]中,而运行时文字池成为常量池的一部分。文字池的好处,是该池中所有相同的字符串常量被合ƈQ只占用一个空间。我们知道,对两个引用变量,使用==判断它们的值[引用]是否相等Q即指向同一个对象:
String s1 = "abc" ; String s2 = "abc" ; if( s1 == s2 ) System.out.println("s1,s2 refer to the same object"); else System.out.println("trouble");
q里的输出显C,两个字符串文字保存ؓ一个对象。就是说Q上面的代码只在pool中创Z一个String对象?br /> 现在看String s = new String("abc");语句Q这?abc"本n是pool中的一个对象,而在q行时执行new String()Ӟpool中的对象复制一份放到heap中,q且把heap中的q个对象的引用交ls持有。okQ这条语句就创徏?个String对象?br />
String s1 = new String("abc") ; String s2 = new String("abc") ; if( s1 == s2 ){ //不会执行的语句}
如果是基本数据类型,则如同首先{换成其包装类对象Q如int x视ؓ转换成Integer(x)? 现在全部统一到引用类型向String的{换了。这U{换如同[as if]调用该对象的无参数toStringҎ。[如果是null则{换成"null"]。因为toStringҎ在Object中定义,故所有的c都有该ҎQ而且Boolean, Character, Integer, Long, Float, Double, and String改写了该Ҏ? 关于+是串接还是加法,由操作数军_?+2+str+3+4 很Ҏ知道?3jf34"。[BTW :在JLS?5.18.1.3中D的一个jocular little exampleQ真的很无趣。] 下面的例子测试了改写toStringҎ的情??br />
class A{ int i = 10; public static void main(String []args){ String str = new String("jf"); str += new A(); System.out.print(str); }
public String toString(){ return " a.i ="+i+"\n"; } }
三、字W串转换的优?br /> 按照上述说法Qstr = 1+2+str+3+4;语句g应该应该生?个String对象Q?br /> 1+2 Q?Qthen 3↺nteger(3)?3" in pool? [假设如此] "3"+str(in heap) = "3jf" (in heap) "3jf" +3 ,first 3↺nteger(3)?3" in pool? [则不创徏] then "3jf3" "3jf3"+4 create "4" in pool then "3jf34"
q里我ƈ不清??转换成字W串后是否在池中Q所以上q结果仍然是猜测?br /> Z减少创徏中间q渡性的字符串对象,提高反复q行串接q算时的性能Qa Java compiler可以使用StringBuffer或者类似的技术,或者把转换与串接合q成一步。例如:对于 a + b + c QJava~译器就可以它视ؓ[as if]
new StringBuffer().append(a).append(b).append(c).toString();
可见Qstr1与str2指向同一个对象,q个对象在pool中。所有遵循Java Language Spec的编译器都必d~译时对constant expressions q行化。JLS规定QStrings computed by constant expressions (ý15.28) are computed at compile time and then treated as if they were literals.