首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 分享:一道BT试题 [已结贴,结贴人:java2000_net]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-13 21:28:28 楼主
    近日,在下到某公司面试,满怀信心的我重重的载在那份BT试题上。
        其中一道:
        以下code生成几个String对象
        String   a= "abc ";
        String   b= "abc ";
        String   c=new   String( "abc ");
        String   d=c.intern();

        当时在下毫不忧郁的选3。
        后来在Java   Language   Specification/CHAPTER   3/Lexical   Structure发现这样一个测试代码,知道错了。

        package   testPackage;
        class   Test   {
    public   static   void   main(String[]   args)   {
        String   hello   =   "Hello ",   lo   =   "lo ";
        System.out.print((hello   ==   "Hello ")   +   "   ");
        System.out.print((Other.hello   ==   hello)   +   "   ");
        System.out.print((other.Other.hello   ==   hello)+ " ");
        System.out.print((hello   ==   ( "Hel "+ "lo "))   +   "   ");
        System.out.print((hello   ==   ( "Hel "+lo))   +   "   ");
        System.out.println(hello   ==   ( "Hel "+lo).intern());
    }
        }
          class   Other   {   static   String   hello   =   "Hello ";   }
       
        学海无崖,顿感羞愧,特此分享。
    20  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-13 21:32:541楼 得分:1
    two?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-13 21:41:232楼 得分:1
    2个
    常量池中一个,堆中一个。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-13 22:39:123楼 得分:1
    我发现这个错误很多人犯。为什么会这样呢?难道老师不好?或者没看到好书?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-13 23:02:384楼 得分:1
    学习了.谢谢教导
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-13 23:12:265楼 得分:1
    我怎么感觉是创建了一个对象呢,难道 "String   d=c.intern(); "也是对象的创建,没怎么见过.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-13 23:50:296楼 得分:1
    to:toploveall  
    String   b= "abc ";
        String   c=new   String( "abc ");
    这两句分别创建两个
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-14 10:59:297楼 得分:1
    顶.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-14 13:23:088楼 得分:1
    String   a= "abc ";
    String   b= "abc ";
    String   c=new   String( "abc ");
    String   d=c.intern();

    其中abd属于常量池,c属于堆
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • wdman
    • 等级:
    发表于:2007-01-14 23:04:529楼 得分:1
    唉,还真不知道。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-18 18:27:4510楼 得分:1
    String   s   =   new   String( "abc ");创建了几个String   Object?
    引用变量与对象的区别;  
    字符串文字 "abc "是一个String对象;  
    文字池(pool   of   literal   strings)和堆(heap)中的字符串对象。

            一、引用变量与对象:除了一些早期的Java书籍和现在的垃圾书籍,人们都可以从中比较清楚地学习到两者的区别。
                    A   aa;
                    这个语句声明一个类A的引用变量aa[我们常常称之为句柄],而对象一般通过new创建。所以题目中s仅仅是一个引用变量,它不是对象。

            二、Java中所有的字符串文字[字符串常量]都是一个String的对象。有人[特别是C程序员]在一些场合喜欢把字符串 "当作/看成 "字符数组,
                    这也没有办法,因为字符串与字符数组存在一些内在的联系。事实上,它与字符数组是两种完全不同的对象。

                    System.out.println( "Hello ".length());
                    char[]   cc={ 'H ', 'i '};
                    System.out.println(cc.length);

            三、字符串对象的创建:
                    由于字符串对象的大量使用(它是一个对象,一般而言对象总是在heap分配内存),Java中为了节省内存空间和运行时间
                    (如比较字符串时,==比equals()快),在编译阶段就把所有的字符串文字放到一个文字池(pool   of   literal   strings0中,
                    而运行时文字池成为常量池的一部分。文字池的好处,就是该池中所有相同的字符串常量被合并,只占用一个空间。
                    我们知道,对两个引用变量,使用==判断它们的值(引用)是否相等,即指向同一个对象:

        String   s1   =   "abc "   ;
        String   s2   =   "abc "   ;
        if(   s1   ==   s2   )   System.out.println( "s1,s2   refer   to   the   same   object ");
        else       System.out.println( "trouble ");
                   

            这里的输出显示,两个字符串文字保存为一个对象。就是说,上面的代码只在pool中创建了一个String对象。

            现在看String   s   =   new   String( "abc ");语句,这里 "abc "本身就是pool中的一个对象,而在运行时执行new   String()时,
            将pool中的对象复制一份放到heap中,并且把heap中的这个对象的引用交给s持有。ok,这条语句就创建了2个String对象。


            String   s1   =   new   String( "abc ")   ;
            String   s2   =   new   String( "abc ")   ;
            if(   s1   ==   s2   ){   //不会执行的语句}
           

            这时用==判断就可知,虽然两个对象的 "内容 "相同(equals()判断),但两个引用变量所持有的引用不同,

            BTW:上面的代码创建了几个String   Object?   (三个,pool中一个,heap中2个。)
            (Java2   认证考试学习指南   (第4版)(   英文版)p197-199有图解。)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-18 22:28:3911楼 得分:1
    2个~~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-18 22:37:5912楼 得分:1
    up
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-18 22:40:1413楼 得分:1
    楼上的   精辟!!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-19 09:36:3414楼 得分:1
    Java把内存划分成两种:一种是栈内存,一种是堆内存。      
           
        在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。      
           
        当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。      
           
        堆内存用来存放由new创建的对象和数组。      
           
        在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。      
           
        在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。      
           
        引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。      
           
     
     
                         

    具体的说:
    栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。  
                        Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。  
                      栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量(,int,   short,   long,   byte,   float,   double,   boolean,   char)和对象句柄。  
                      栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:  
    int   a   =   3;  
    int   b   =   3;  
    编译器先处理int   a   =   3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int   b   =   3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。这时,如果再令a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b,   它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。  

    String是一个特殊的包装类数据。可以用:  
    String   str   =   new   String( "abc ");  
    String   str   =   "abc ";  
    两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。  
    而第二种是先在栈中创建一个对String类的对象引用变量str,然后查找栈中有没有存放 "abc ",如果没有,则将 "abc "存放进栈,并令str指向”abc”,如果已经有”abc”   则直接令str指向“abc”。  

                          比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。  
    String   str1   =   "abc ";  
    String   str2   =   "abc ";  
    System.out.println(str1==str2);   //true  
    可以看出str1和str2是指向同一个对象的。  

    String   str1   =new   String   ( "abc ");  
    String   str2   =new   String   ( "abc ");  
    System.out.println(str1==str2);   //   false  
    用new的方式是生成不同的对象。每一次生成一个。  
                  因此用第二种方式创建多个”abc”字符串,在内存中其实只存在一个对象而已.   这种写法有利与节省内存空间.   同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String   str   =   new   String( "abc ");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。  
                  另一方面,   要注意:   我们在使用诸如String   str   =   "abc ";的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。只有通过new()方法才能保证每次都创建一个新的对象。   由于String类的immutable性质,当String变量需要经常变换其值时,应该考虑使用StringBuffer类,以提高程序效率
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-19 09:40:1415楼 得分:0
    intern
    public   String   intern()返回字符串对象的规范化表示形式。  
    一个初始时为空的字符串池,它由类   String   私有地维护。  

    当调用   intern   方法时,如果池已经包含一个等于此   String   对象的字符串(该对象由   equals(Object)   方法确定),则返回池中的字符串。否则,将此   String   对象添加到池中,并且返回此   String   对象的引用。  

    它遵循对于任何两个字符串   s   和   t,当且仅当   s.equals(t)   为   true   时,s.intern()   ==   t.intern()   才为   true。  

    所有字面值字符串和字符串赋值常量表达式都是内部的。字符串字面值在《Java   Language   Specification》的   §3.10.5   中已定义。  


    返回:
    一个字符串,内容与此字符串相同,但它保证来自字符串池中。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-19 10:15:0016楼 得分:0
    String   a= "abc ";                                                                     yes
        String   b= "abc ";                                                                       no
        String   c=new   String( "abc ");                                       yes
        String   d=c.intern();                                                               这句是关键!!

          按照jdkzhog   对   .intern   的说明似乎还不是很充分。
            String   c=new   String( "abc ");                                    
            String   d=c.intern();                            
            如果仅仅是这样  
            c   ==   d     ?   结果是   false;
            但是考虑到堆内存中已经有   a所指向的那个“abc”了   ,所以   d   就指向了a
            于是                              
                c   ==   d   ,       c   ==   d   就对了。


      所以这条的答案是2
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-19 22:45:2117楼 得分:1
    mark
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-20 11:30:3018楼 得分:0
    纠正一下,

    我上面说错了一句话。

      但是考虑到堆内存中已经有   a所指向的那个“abc”了   ,所以   d   就指向了a
            于是                              
                c   ==   d   ,       c   ==   d   就对了。   ==   〉   a   ==d,   b   ==d
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-20 11:55:2819楼 得分:1
    mark
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-20 12:47:2620楼 得分:1
    学习了~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-20 13:00:5921楼 得分:1
    赶紧去翻书
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-20 13:25:0822楼 得分:1
    学习一下
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-21 11:56:1723楼 得分:1
    基础没有掌握好
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-21 13:15:1724楼 得分:0
    感觉跟高考语文题似的。
    中国的考试制度造就了多少孔乙己、范进啊。
    这种读书虫有什么用?现在破公司尽招一些coder做八股文。我最痛恨这种试题了,要考就考数据结构,要考就考设计模式,尽考些“回”字有几种写法的试题。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-01-22 11:48:2825楼 得分:0
    String   str   =   new   String( "abc ");

    到底创建了几个对象,现在说法不一啊,不知道该听谁的啦

    请问各位高手,创建了几个对象,是哪几个对象,小弟在此谢过

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • john_sheep
    • 等级:
    发表于:2007-01-22 16:02:0526楼 得分:0
    感觉跟高考语文题似的。
    中国的考试制度造就了多少孔乙己、范进啊。
    这种读书虫有什么用?现在破公司尽招一些coder做八股文。我最痛恨这种试题了,要考就考数据结构,要考就考设计模式,尽考些“回”字有几种写法的试题。


    同意
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-03-16 10:47:5127楼 得分:0
    luyang1016(闭月羞花猫)  
    goog!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-03-16 11:07:0028楼 得分:0
    学习中,但是有用吗?
    同意john_sheep!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-03-16 11:24:1529楼 得分:0
    我是初学者感觉上是很难的,不过也略为能看懂吧!感觉上真是相差太多,我还得努力才行呀!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-03-16 11:25:1030楼 得分:0
    也不能这么说吧,至少加深理解
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-03-16 11:45:3831楼 得分:0
    张见识
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2007-03-16 11:53:4432楼 得分:0
    MARK
    修改 删除 举报 引用 回复