`

JAVA面试题解惑系列(二)——到底创建了几个String对象?

阅读更多
removed.

请到博文下载PDF文件:http://zangweiren.iteye.com/blog/241218
82
7
分享到:
评论
20 楼 臧圩人 2008-07-01  
回复zzmacoolboy:
第一题:
s1和s2都是变量,因此它们通过“+”运算得出的s3的值在编译期无法确定,只能在运行时确定。因为在运算出s3的值之前,s1和s2的值都有可能被其他类的方法改变,因此s3是运行时新建的对象,和s4不是一个,因此输出false。

第二题:
s1和s2都是以确定的常量,因此s3的值在编译期已经确定,它只能是“Hello,World”,因此s3的定义等同于:
String s3="Hello,World";

故s3和s4是同一个对象,程序输出结果为true。

第三题:
s1和s2虽然被定义为常量(只能被赋值一次),但是它们都没有马上被赋值。在运算出s3的值之前,他们何时被赋值,以及被赋予什么样的值,都是个变数。因此s1和s2在被赋值之前,性质类似于一个变量。参照第一题的理论,输出结果应为false。
19 楼 minisoft 2008-07-01  
还是挺诡异的。那我先问诸位一个问题:
如果直接是  new String("abc")的话。这里创建了两个对象不必说。
但是,这两个中,那个立即失去了引用呢?new的那个应该。但“abc”是否还被关注,即还被放在字符串pool中?
谢谢!
18 楼 zzmacoolboy 2008-07-01  
/**  
   字符串测试题1  
   @author Eastsun  
*/  
public class StrTest1 {   
    static String s1 ="Hello,";   
    static String s2 ="World";   
       
    public static void main(String[] args){   
        String s3 = s1 + s2;   
        String s4 ="Hello,World";   
        System.out.println(s3==s4);   //输出为false
    }   
}  


/**  
   字符串测试题2  
   @author Eastsun  
*/  
public class StrTest2 {   
    final static String s1 ="Hello,";   
    final static String s2 ="World";   
       
    public static void main(String[] args){   
        String s3 = s1 + s2;   
        String s4 ="Hello,World";   
        System.out.println(s3==s4);   //输出为true
    }   
}  



/**  
   字符串测试题3  
   @author Eastsun  
*/  
public class StrTest3 {   
    final static String s1;   
    final static String s2;   
    static {   
        s1 ="Hello,";   
        s2 ="World";   
    }   
       
    public static void main(String[] args){   
        String s3 = s1 + s2;   
        String s4 ="Hello,World";   
        System.out.println(s3==s4);   //输出为false 
    }   
}  


解释一下这几道题目吧,越来越糊涂了.
17 楼 臧圩人 2008-07-01  
回复yinleiyoung:
我来回答一下吧。
常量的值在编译的时候已经被确定了,例如:
String a="ab"+"cd";

由于"ab"和"cd"都是常量,因此变量a的值在编译时就可以确定,故这行代码编译后等同于下面这行代码:
String a="abcd";
16 楼 yinleiyoung 2008-07-01  
To Eastsun:

大哥帮忙解释一下,不太懂。

谢谢!
15 楼 yinleiyoung 2008-07-01  
留心,学习
14 楼 臧圩人 2008-07-01  
回复Eastsun:
谢谢你的更正! 
13 楼 Eastsun 2008-07-01  
臧圩人 写道
对于第三个例子:
 String a="ab"+"cd";  



"ab"和"cd"分别创建了一个对象,它们经过“+”连接后又创建了一个对象"abcd",因此一共三个,并且它们都被保存在字符串池里了。



这个结论四错误的。
事实上只有一个String对象“abcd”被建立。
而且这段代码等价于:
引用
String a="abcd";


如果有异议,你们可以把上面两段代码编译后然后再用反编译工具反编译一下,看看得到的代码是不是一样的。

不过,我可以给出更有力的理由,根据《Java Language Spec 3.0》3.10.5(第29页)

引用

• Literal strings within the same class (§8) in the same package (§7) represent
references to the same String object (§4.3.1).
• Literal strings within different classes in the same package represent references
to the same String object.
• Literal strings within different classes in different packages likewise represent
references to the same String object.
• Strings computed by constant expressions (§15.28) are computed at compile
time and then treated as if they were literals.

• Strings computed by concatenation at run time are newly created and therefore
distinct.


注意标红色的一行:常量表达式在编译期间被计算。
就是说:"ab"+"cd"在编译阶段已经变成“abcd”了,何来“ab”与“cd”?


顺便也出几道字符串有关的题给大家做做:

不编译运行代码,下列代码的输出应该是什么?

/**
   字符串测试题1
   @author Eastsun
*/
public class StrTest1 {
    static String s1 ="Hello,";
    static String s2 ="World";
    
    public static void main(String[] args){
        String s3 = s1 + s2;
        String s4 ="Hello,World";
        System.out.println(s3==s4);
    }
}


/**
   字符串测试题2
   @author Eastsun
*/
public class StrTest2 {
    final static String s1 ="Hello,";
    final static String s2 ="World";
    
    public static void main(String[] args){
        String s3 = s1 + s2;
        String s4 ="Hello,World";
        System.out.println(s3==s4);
    }
}


/**
   字符串测试题3
   @author Eastsun
*/
public class StrTest3 {
    final static String s1;
    final static String s2;
    static {
        s1 ="Hello,";
        s2 ="World";
    }
    
    public static void main(String[] args){
        String s3 = s1 + s2;
        String s4 ="Hello,World";
        System.out.println(s3==s4);
    }
}

12 楼 臧圩人 2008-07-01  
回复zzmacoolboy:
我们这么来理解吧。JAVA虚拟机用堆来存储对象,堆是位于内存中的一块存储空间,字符串池也位于内存中。
那么,在执行String a="abc";时,"abc"在堆中被创建,并且之后也被加到了字符串池中,实际上只是字符串池中的某个变量保存了"abc"对象的引用。
就像这样:
String a="abc";
String b="abc";

我们虽然创建了a和b两个变量,但是他们都是指向"abc"这一个对象,而"abc"是保存在堆中的。
11 楼 qcm840503 2008-07-01  
惭愧呀~干了一年的活~对这个还没有了解的这么透呀~!自卑呀~~~~呵呵
10 楼 zzmacoolboy 2008-07-01  
引用
String e = a + "cd";
 
像这样的话,a + "cd" 的值应该已经赋值给了e吧,而不是楼主说的单独的 new String()这种情况,那这样的话,e变量应该是要指向"abcd"这个值的,至少我们打印出来e的值是"abcd",那这个时候不是在字符串池中,那指向的是哪呢?
请楼主帮忙分析一下,谢谢!
9 楼 臧圩人 2008-07-01  
回复zzmacoolboy:
这些对象被加到字符串池中,只是我们的程序中没有指向它们的变量罢了。
就像下面这样:
new String();

这里我们创建了一个对象,但是并没有把它的引用赋值给任何一个变量。
8 楼 zzmacoolboy 2008-07-01  
引用
String a = "ab";
String b = "cd";
"ab"+"cd" 创建的对象 "加入了" 字符串池中
a +"cd" 创建的对象 "没加入" 字符串池中
"ab"+ b 创建的对象 "没加入" 字符串池中
a + b 创建的对象 "没加入" 字符串池中


从输出的结果可以看到只有 "ab"+"cd"创建的对象加入了字符串池中,其它的的都没有加入字符串池中,请问一下楼主那e,f,g引用到底指向哪了呢?
7 楼 liudaoru 2008-07-01  
确实不错,以前都没怎么深入的思考过这个问题,看起来以后应该多看看java虚拟机的机制
6 楼 wutao8818 2008-07-01  
SCJP考点
5 楼 spiritfrog 2008-07-01  
好文啊!说到了java不被注意的微小地方
4 楼 sariy 2008-07-01  
很好 很强大!
3 楼 naff 2008-07-01  
好,收藏...
2 楼 Rooock 2008-06-30  
一定要收藏..一定要收藏...!
1 楼 zzq230 2008-06-30  
good good good

相关推荐

    JAVA面试题解惑系列(二)——到底创建了几个String对象-JAVA程序员JAVA工程师面试必看.pdf,这是一份不错的文件

    JAVA 面试题解惑系列之 String 对象创建机制 本文将深入探讨 JAVA 中 String 对象的创建机制,解答常见的面试题目,并探索 String 对象池的概念和机制。 一、String 对象的创建方式 在 JAVA 中,String 对象可以...

    JAVA面试题解惑系列合集

    .3 1.2 JAVA面试题解惑系列(二)——到底创建了几个String对象? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8 1.3 JAVA面试题解惑系列(三)——变量(属性)的覆盖 . . . . . . . . . . . . ....

    臧圩人--JAVA面试题解惑系列合集.pdf

    **1.2 JAVA面试题解惑系列(二)——到底创建了几个String对象?** - **知识点**:探讨Java中String对象的创建机制,特别是常量池的概念和String对象的内存分配策略。了解字符串字面量与`new String()`的区别,以及...

    JAVA面试题解惑系列.rar

    这个压缩包可能包含了两本书籍,一本是"JAVA面试题解惑系列.pdf",另一本是"臧圩人--JAVA面试题解惑系列合集.pdf"。这些资源旨在帮助求职者准备Java开发相关的面试,提升他们对Java技术的理解和应用能力。 在Java...

    Java面试题解惑系列

    2、到底创建了几个String对象;3、变量(属性)的覆盖;4、final,finally,finalize;5.传了值还是传了引用;6.String杂谈;7.日期与时间的处理;8.基本类型总结;9.继承,多态,重载,重写;10.多线程;11.运算符...

    Java面试题详解,和一些基础知识的深入剖析,个人认为非常棒

    首先,我们来看“JAVA面试题解惑系列(二)——到底创建了几个String对象?”这个问题。在Java中,String是不可变的,这意味着一旦创建,其内容就不能改变。因此,每当对String进行操作,如拼接或赋值,实际上可能...

    《经典JAVA面试题解惑系列合集(臧圩人)》

    《经典JAVA面试题解惑系列合集(臧圩人)》这本书很可能就是针对这些问题进行深入解析的一本指南。 首先,Java的基础知识是面试中的必考部分。这包括但不限于Java语法、数据类型、控制结构(如if语句、for循环、...

    JAVA面试题解惑系列

    【JAVA面试题解惑系列】是一系列专门针对Java开发者面试准备的文章集合,涵盖了多个核心Java概念和面试常问问题。作者臧圩人在JavaEye社区分享了这个系列,旨在帮助求职者理解和解答面试中可能出现的疑问。 1. **类...

    JAVA面试题解惑系列——类的初始化顺序

    在Java中,类的初始化顺序是一个经常被问及的面试题目,尤其对于Java程序员和工程师来说,了解这个知识点是必须的。在Java中,类的初始化顺序是面试中的经典问题之一,它涉及到继承、静态成员以及实例成员等多个方面...

    JAVA面试题解惑系列(六)——字符串(String)杂谈[收集].pdf

    Java中的字符串(String)是编程面试中的热门话题,其特性与操作是面试官常常用来考察候选人基础知识的手段。本文将深入探讨String对象的一些关键知识点。 首先,我们要了解`String`类的`length()`方法。这个方法返回...

    JAVA面试题解惑系列(一)——类的初始化顺序-JAVA程序员JAVA工程师面试必看.pdf,这是一份不错的文件

    JAVA面试题解惑系列(一)——类的初始化顺序 JAVA 是一门面向对象的编程语言,类的初始化顺序是 JAVA 程序员和 JAVA 工程师面试中一个非常重要的知识点。本文将详细讲解类的初始化顺序,并提供了相关的测试代码,...

    JAVA面试题解惑系列.doc

    《JAVA面试题解惑系列——类的初始化顺序》 在Java编程中,理解类的初始化顺序是面试中常见的考察点,因为它直接关系到程序的执行逻辑。本文将深入探讨类的初始化过程,以及在继承场景下如何理解这个过程。 首先,...

    115个Java面试题和答案——终极列表

    Java面试题是每个Java开发者在求职过程中必须面对的挑战,涵盖范围广泛,从基础概念到高级特性和设计模式。这份终极列表包含115个Java面试题和答案,旨在帮助求职者全面准备,以期在面试中表现出色。以下是部分核心...

    JAVA面试题解惑系列合集.docx

    本文通过对Java面试题中的两个典型问题——类的初始化顺序和String对象的创建——进行了深入分析。这些知识点不仅是Java编程的基础,也是深入理解Java语言特性的关键。掌握这些内容不仅能够帮助开发者在面试中表现...

Global site tag (gtag.js) - Google Analytics