自己想的一道题,算是30%原创吧
String a=new String("Hello");
a+="World";
问:a的内容最后是什么?
这两个语句,共生成了几个Java对象?
简单不?看样子非常简单吧,呵呵。
第一问:a(确切地说a引用的内容)是HelloWorld
第二问: 两个语句,一共生成了几个对象?
看第一个语句,说实话,用这种方式初始化String,实在是代码垃圾。这先不管啦。这个语句是老生长谈,一个或两个对象。
为何?第一次执行时创建了二个, 一个为字面量"Hello"(它本身是一个String对象), 一个为new String("Hello")(它是通过new创建的, 功能上和字面量"foo"完全一样, 但却是另一个对象).
第二次执行时, 只创建一个, 即new String("Hello"), 这是因为: "Hello"作为String字面量, 是存在于String Pool里面的, 第二次使用它时, 直接指向原有的String, 而不再创建新的String; 但new String("Hello")却每执行一次都创建一个新的,完全一样的String对象.
第二个语句呢?
3个对象。
首先是“World”,毋庸质疑。
那么然后呢?注意了,String是final类,不可改变。平时我们写Java会有个错觉,stringA+stringB就以为是前者尾巴接上后者脑袋。的确,在C/C++里就是如此。一点儿错都没有。
但是Java不是,Java设计者为了更多方面的考虑,他们把String设计成了final。
看一下JVM汇编指令吧
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
static void inti();
Code:
0: new #2; //class java/lang/String
3: dup
4: ldc #3; //String Hello
6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_0
10: new #5; //class java/lang/StringBuilder
13: dup
14: invokespecial #6; //Method java/lang/StringBuilder."<init>":()V
17: aload_0
18: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: ldc #3; //String Hello
23: invokevirtual #7; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
26: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
29: astore_0
30: return
}
仔细看一下我做的标记,JVM给我们生成了一个StringBuilder类。(我用的是JDK5,旧版本是StringBuffer类,单单这一点小改动就能让Java的速度提高很多)。让后用append方法载入Hello和World两个String的引用(明确地说转化成字符数组)。
当载入完成后,StringBuilder实例调用toString,生成一个新的String实例(暂时称为TempString)。
最后把引用a指向TempString
总结:两句语句总共生成了4个或5个Java类实例
PS:Java中没有指针实在是太不方便了。特别是在操作原始数据类型的时候。个人认为Java应该在这点上学学C#。指针不是洪水猛兽,对优秀程序员而言,指针是编程中的一种享受。
希望“海豚”(Java7)能出现指针吧---很不现实,还是等开源后的Java版本吧
posted on 2006-08-14 03:18
murainwood 阅读(500)
评论(4) 编辑 收藏 所属分类:
Java读书笔记