常见Java面试题 – 第一部分:非可变性(Immutability)和对象引用(Object reference)

ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一。请看此系列相关面试题。你可以从这里查看全部的Java面试系列。

一些比较核心的Java问题经常会用来考验面试者的Java基本知识功底。这篇文章列出来了一些在我的书里面没有的面试题,通过这些面试题读者也可以梳理一下Java基础知识点。

Q1.下面的代码片段会输出什么?

String s = " Hello ";
s += " World ";
s.trim( );
System.out.println(s);

A1.正确输出是” Hello  World “。

由于字符串前后都有空格,因为有些人可能会认为结果是”Hello World”。那么,这个题目想要考察的是什么呢?

1.  字符串对象(String Object)是非可变的(immutable),这个题目容易迷惑人的地方在s.trim( )这一行。

2.  理解对象引用和不可达对象会由垃圾回收器收集。

顺着这个题目,你觉得还可以考察哪些概念呢?

1.  例如,上面的代码中一共会生成几个字符串对象,什么时候这些对象会变成不可达对象从而被垃圾回收器回收。

2.  又比如,上面的代码的效率如何?

最好的解释方式是通过一个图表来说明,如下:

如果需要输出前后没有空格的”Hello World”,那么应该将s.trim( )再赋值给”s”。这个赋值操作可以让s指向新创建出来的字符串对象。

上面的代码也可以改写成如下方式:

StringBuilder sb = new StringBuilder(" Hello ");
sb.append(" World ");
System.out.println(sb.toString().trim( ));

StringBuilder不是一个线程安全的类,因此仅仅用作本地变量是没有问题的。如果你希望用作实例变量,那么可以选择线程安全的StringBuffer类。想知道字符串操作背后的原理吗?可以点击这里:String concatenation

扩展阅读:

 

英文原文: Java Success,编译:ImportNew - 郑雯

译文链接:http://www.importnew.com/2217.html

【如需转载,请在正文中标注并保留原文链接、译文链接和译者等信息,谢谢合作!】

关于作者: 郑雯

2009年北航计算机学院毕业,加入IBM CDL至今。从事过web产品测试及开发工作。目前兴趣主要在游泳和自助穷游上。

查看郑雯的更多文章 >>



相关文章

发表评论

Comment form

(*) 表示必填项

4 条评论

  1. zhangjg 说道:

    我认为如果编译器优化的能力比较强的话, 不会生成” Hello ” 和 ” World “这两个字符串。如果编译器发现
    String s = ” Hello “;
    s += ” World “;
    这两句代码中的两个常量是连在一起的, 应该直接优化成” Hello World “这一个字符串

    Thumb up 0 Thumb down 0

    • 刘志军 说道:

      编译器具体怎么优化的,可以用javap 命令查看究竟发生了什么
      Code:
      0: ldc #2; //String Hello
      2: astore_1
      3: new #3; //class java/lang/StringBuilder
      6: dup
      7: invokespecial #4; //Method java/lang/StringBuilder.”“:()V
      10: aload_1
      11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      14: ldc #6; //String World
      16: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      19: invokevirtual #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      22: astore_1
      23: aload_1
      24: invokevirtual #8; //Method java/lang/String.trim:()Ljava/lang/String;
      27: pop
      28: getstatic #9; //Field java/lang/System.out:Ljava/io/PrintStream;
      31: aload_1
      32: invokevirtual #10; //Method java/io/PrintStream.println:(Ljava/lang/String;)V

      Thumb up 0 Thumb down 0

      • zhangjg 说道:

        我记错了, 原来是用StringBuilder直接实现了拼接。下面的代码是直接在编译时期优化成一个字符串的:

        class StringTest 
        {
        	public static void main(String[] args) 
        	{
        		test1();
        		test2();
        	}
        
        	static void test1(){
        		String a = " Hello " + " World ";
        		System.out.println(a);
        	}
        }
        

        以下是javap的结果:
        static void test1();
        Code:
        0: ldc #4; //String Hello World
        2: astore_0
        3: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
        6: aload_0
        7: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/Str
        ing;)V
        10: return

        Thumb up 0 Thumb down 0

  2. david.dai 说道:

    说的不错~

    Thumb up 0 Thumb down 0

跳到底部
返回顶部