继续巩固Java基础,一道综合题

继续巩固Java基础,一道综合题

自己想的一道题,算是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版本吧


你可能感兴趣的:(继续巩固Java基础,一道综合题)