今天看"Java Performance Tuning",书中提到下面的过程无论何时被调用都会产生两个临时字符串对象然后就被丢弃了。public String sayHi(String title, String name)
{
return "hi " + title + " " + name;
}我猜测这里面产生的两个对象应该是"hi "和" ",但是我理解这两个对象应该是从String pool产生的吧,如果String pool没有这两个对象,会新生成,如果已经存在那么应该直接返回这两个对象。所以应该不会存在书中提到的现象。不知道我的理解是否正确,请各位指正。
{
return "hi " + title + " " + name;
}我猜测这里面产生的两个对象应该是"hi "和" ",但是我理解这两个对象应该是从String pool产生的吧,如果String pool没有这两个对象,会新生成,如果已经存在那么应该直接返回这两个对象。所以应该不会存在书中提到的现象。不知道我的理解是否正确,请各位指正。
最后被丢弃的应该是复制的那两个String对象...
最后被丢弃的应该是复制的那两个String对象...
--------------------------------------------------------------------------嗯,有道理。不过,String对象具有恒常性的,不会被修改,操作String对象的方法都会返回一个新的Stirng对象,那么应该直接从池中取出对象,复制一份好像没什么意义吧。
Code:
0: new #2; //class java/lang/StringBuilder
3: dup
4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V
7: ldc #4; //String hi
9: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
12: aload_1
13: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
16: ldc #6; //String
18: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
21: aload_2
22: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
25: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/la
ng/String;
28: areturn
所有操作都针对副本进行....操作结束副本就被回收了...也就是说String池子不是冰箱:冷冻-->取出来使用-->用完继续冷冻
而更接近于画廊:展品-->照着展品画个复制品-->有新画-->把新画放进画廊...所以String效率不如StringBuffer高喵~~~~
还有个问题就是如果改成"return (new StringBuffer( )).append("hi ").append(title).append(" ").append(name).toString( );",难道就不会产生这两个额外的对象吗?
String池子的相关操作应该是JVM自己做的吧,这个在字节码里是看不出来的...
只能看到关于String类的append操作过程:转化为StringBuilder或者StringBuffer来进行,最后toString一个新String作为结果.
字节码的9,13,18,22行所用到的String(应该分别是"hi",title," ",name)都已经是副本了...
这么说貌似怪怪的,String不是Java的那8种基础类型之一,常量/变量容易说糊涂,把它看作一个特殊点的类更好理解....9楼的例子不会有额外对象,其实String的相加本来也都是转化为StringBuffer之后进行的...更正我8楼的错误: "hi"这样的对象是直接引用String池的,new出的对象才是副本,谢谢lz在6楼指出....
他和string是不同的
string 他是一个引用类型 当他连接字符串的时候 他所连的hi 和 "" 也同样占用内存创建他们 之后再连接起来