1和2等价
3只是声明,没有赋值
String在JAVA中比较特殊

解决方案 »

  1.   

    同时楼上的,String在java中是作为一个对象出现的。
      

  2.   

    String 是Java中最特殊的对象。
      

  3.   

    s1.equals(s2)的值是true。
    s3只声明,没有初始化(也就是没有赋值)。
    String s3=null;则初始化了,但是s3指向null。
      

  4.   

    String s1 = new String("Happy");
    String s2 = "Happy";
    String s3;
    之间的区别?
    你说前两个一样么??好像是不对吧?S1是一个对象的句柄,在存堆中。S2是一个JAVA的基本类型,它其中存放的是一个字符串,是放在椎栈中。
    不知我这样认为对不对??
      

  5.   

    同意 xuwedo2003(体味过程) ,s1和s2所在内存空不一样,但好像也没什么影响,和C++不同的是,在Java中直接返回堆栈内对象引用也没问题。
      

  6.   

    String s1 = new String("Happy");
    String s2 = "Happy";
    String s3;
    其中s1,s2,s3都是句柄,指向字符串对象. 当然,s3没有初始化,它指向的是null
    s1 equals s2 但 s1 != s2 .s1,s2指向两个对象..
    如果再定义一个 String s4 = "Happy"
     则 s2==s4 .当然肯定s2 equals s4 ,因为s2和s4都指向同一个对象 ..呵呵,慢慢理解吧:) ------------------------------------------------------
               我们还年轻牛奶会有的奶牛也会有的 
                 可天天在 csdn 混这些会有吗 ??
      

  7.   

    刚才忘了一点,xuwedo2003(体味过程)说s2是基本类型,钝书生不敢苟同,String并不是基本类型,它也是从java.lang.Object派生出来的,跟int, long, float, double, char, boolean等基本类型是不同的。只是它放在java.lang包中,可以直接引用而已。
      

  8.   

    String s1 = new String("Happy");
    String s2 = "Happy";
    JAVA语言对String作了一些特殊处理,JAVA中唯一的一个运算符重载就是String 的等号
    也就是你写的是s2 = "happy",但编译器给你处理成s2 = new String("happy");
    所在happy也是在堆中
      

  9.   

    String s1 = new String("Happy");
    String s2 = "Happy";
    看着是等价没错,但是绝对不一样的.String s1 = new String("Happy");是一个愚蠢的反例.如果大家会用javap,可以做试验看看.
    另外, String s2 = "happy" 是从class的常量池中加载的.
      

  10.   

    给大家做一个小小的例子:
    public class TestString {
        public static void main(String[] args) {
            long start = System.currentTimeMillis();
            for ( int i=0; i<10000000; i++ ) {
                    String s1 = new String("Happy");
            }
            long end = System.currentTimeMillis();
            System.out.println("Duration:"+(end-start));
     
            start = System.currentTimeMillis();
            for ( int i=0; i<10000000; i++ ) {
                    String s1 = "Happy";
            }
            end = System.currentTimeMillis();
            System.out.println("Duration:"+(end-start));
        }
    }
    运行结果如下:
    [zxh@spider zxh]$ java TestString
    Duration:761
    Duration:25
    机器平台:P4 2.0G, Redhat linux 9.0, JDK1.4.1_02
    说等价的朋友跳出来解释吧.
      

  11.   

    再次给楼主写详细一点:String s = new String("Hello");这句反编译过来是这样的:
       0 new #2 <Class java.lang.String>
       3 dup
       4 ldc #3 <String "Hello">
       6 invokespecial #4 <Method java.lang.String(java.lang.String)>
       9 putstatic #5 <Field java.lang.String s>而String s = "Hello";反编译是这样的:
       0 ldc #2 <String "Hello">
       2 putstatic #3 <Field java.lang.String s>我想就不需要再解释是否等价的问题了吧,请仔细看看上面的反编译结果.
      

  12.   

    楼上很厉害哟,这个程序多运行两遍~
      public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
          String s1 = new String("Happy"+i);
        }
        long end = System.currentTimeMillis();
        System.out.println("Duration:" + (end - start));    start = System.currentTimeMillis();
        for (int i = 0; i < 10000000; i++) {
          String s1 = "Happy" + i;
        }
        end = System.currentTimeMillis();
        System.out.println("Duration:" + (end - start));
      }
      

  13.   

    to accp(只有在梦醒的时候才知道自己是做了一个梦):
    老兄想说明什么?还是后面的快啊.看看反编译的结果:
    String s1 = new String("Hello"+i);
    ==========================================
       4 new #3 <Class java.lang.String>
       7 dup
       8 new #4 <Class java.lang.StringBuffer>
      11 dup
      12 invokespecial #5 <Method java.lang.StringBuffer()>
      15 ldc #6 <String "Hello">
      17 invokevirtual #7 <Method java.lang.StringBuffer append(java.lang.String)>
      20 getstatic #2 <Field int i>
      23 invokevirtual #8 <Method java.lang.StringBuffer append(int)>
      26 invokevirtual #9 <Method java.lang.String toString()>
      29 invokespecial #10 <Method java.lang.String(java.lang.String)>
      32 putstatic #11 <Field java.lang.String s>String s1 = "Hello"+i;
    =========================================
       4 new #3 <Class java.lang.StringBuffer>
       7 dup
       8 invokespecial #4 <Method java.lang.StringBuffer()>
      11 ldc #5 <String "Hello">
      13 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)>
      16 getstatic #2 <Field int i>
      19 invokevirtual #7 <Method java.lang.StringBuffer append(int)>
      22 invokevirtual #8 <Method java.lang.String toString()>
      25 putstatic #9 <Field java.lang.String s>运行结果:(三次)
    [zxh@spider zxh]$ java TestString
    Duration:14086
    Duration:10955
    [zxh@spider zxh]$ java TestString
    Duration:14787
    Duration:11848
    [zxh@spider zxh]$ java TestString
    Duration:14699
    Duration:11772
      

  14.   

    :xiaohaiz(老土进城,两眼通红) 
    楼主问的是 s1 s2 s3的区别,不是问怎样做提高性能...
    s1 = new String("ssss") 是开辟一个新内存区域,建立一个新对象
    s2="ssss" 是生成一个String 类型的句柄 s2,而它的值是在常量池里寻找.
    如果再定义一个s3="ssss" ,则这是的s3和s2都指向同一个String,指向同一个对象空间..
    但s1始终是和s2,s3不一样的,它有自己的对象空间..
    这就是 new 和直接 = 的区别...
    所以现在就是 
    s1 equals s2 为true 但 s1==s2为false,而s2==s3为true,当然肯定s2.equale(s3)也为true了 
    至于效率,那不是现在在讨论的 :)
     ------------------------------------------------------
               我们还年轻牛奶会有的奶牛也会有的 
                 可天天在 csdn 混这些会有吗 ??
      

  15.   

    4 new #3 <Class java.lang.String>
     7 dup
     29 invokespecial #10 <Method java.lang.String(java.lang.String)>使用String构造函数,还是要多执行三条指令.
      

  16.   

    至于效率
    for(int i = 0 ;i<100000 ;i++)
    String s1 = "Hello"+i;像这样的情况,用StringBuffer类比String要快 一千倍(或几百倍,以前做的测试,现在忘了) !!! ------------------------------------------------------
               我们还年轻牛奶会有的奶牛也会有的 
                 可天天在 csdn 混这些会有吗 ??
      

  17.   

    to zez(思恩 为老婆多挣钱 鹤清风) :
    多谢解释,其实我明白楼主的意思.对于初学者来说,这个确实没有区别,而且new String()的方式好像还更为合理一点.
    我只是想真正告诉他们new String和=""之后有什么区别,想让他们从开始就养成一个好的习惯来使用String. 等到后面明白String的immutable也就有好处的.
      

  18.   

    再 to zez(思恩 为老婆多挣钱 鹤清风) :
    不是
    for(int i = 0 ;i<100000 ;i++)
    String s1 = "Hello"+i;
    而是:
    String s1 = "Hello";
    for(int i = 0 ;i<100000 ;i++) {s1 += i;}

    StringBuffer sbuf = new StringBuffer("Hello");
    for(int i = 0 ;i<100000 ;i++) {sbuf.append(i);}
    String s1 = sbuf.toString();
    之间的比较.你的记忆没有骗你,确实效率相差太远了. :)
      

  19.   

    :xiaohaiz(老土进城,两眼通红) 
    呵呵,其实你功底很不错呀 :)
    说真的,那些底层的东西,我一直也没有仔细看呢...
    唉,每天光赶项目,还是在学校好,可以自由的研究... 只是在学校的时候光玩了 :) ------------------------------------------------------
               我们还年轻牛奶会有的奶牛也会有的 
                 可天天在 csdn 混这些会有吗 ??
      

  20.   

    to zez(思恩 为老婆多挣钱 鹤清风):
    我上大学四年唯一都坚持下来的就是喝茶打麻将了. :)
      

  21.   

    s1 = new String("ssss") 是开辟一个新内存区域,建立一个新对象
    s2="ssss" 是生成一个String 类型的句柄 s2,而它的值是在常量池里寻找.
    看来是不一样,
    我记得String是个不变类,是说不管你系统中有多少个ssss,它其实是所有的都指向同一个?
    包括你用new String("ssss");
    看来还是new出来了一个,呵,我说错了
    还说错了一个,重载的是"+",不是"="
    sorry~
      

  22.   

    不错不错!看样子要学的东东比我想像的要多得多呀!做为一个初学者,我只能看得懂各位N人所说的一部分,但我会努力的!为了再进一步,请给各位N人说说以下代码:
    public class Test {
     public static void main(String[] args) {
       StringBuffer sb1 = new StringBuffer("a");
       StringBuffer sb2 = new StringBuffer("a");
       System.out.println("sb1.equals(sb2) : " + sb1.equals(sb2));//<1>、为什么是false   String s1 = new String("a");
       String s2 = new String("a");
       String s3 = "ssss";
       String s4 = "ssss";
       System.out.println("s1.equals(s2) : " + s1.equals(s2));//<2>、为什么是true
       System.out.println("s1 == s2 : " + (s1 == s2));//<3>、为什么是false
       System.out.println("s3 == s4 : " + (s3 == s4));//<4>、true
       
     }
    }
     其中<2>、<4>上面的各位已经说清楚了,
    可是<3>呢?是不是说“==”比较是句柄(地址),所以,s1和s2是不一样的?
    <1>呢?请高人给说一说String和StringBuffer的区别??这个问题我一直想知道!!谢谢!!
      

  23.   

    <3>, s1和s2分别是new的两个不同的对象,位于heap中的不同空间,所以s1==s2为false.
    <1>, StringBuffer类没有覆盖equals方法,所以当你对StringBuffer调用equals的时候,实际上是调用起父类Object的equals方法,而Object的equals方法是本地方法,比较的引用是否相等.所以你会得到false.
    这样就是true了: sb1.toString().equals(sb2.toString());String是一个不变类,就是说在其生命周期内不会被改变.(只有在构造的时候才能赋值)
    而StringBuffer是一个可变类.这就是最大的区别.
    关于不变(IMMUTABLE)和可变(MUTABLE)的比较大致是这样的.
    (1) 不变类是线程安全的,强壮;
    (2) 使用不变类可能对造成垃圾对象的增多;
    但是正常情况下,不变对象的优点还是很显著的.
    我们所看到的基本类型的封装类都是不可变类,如Strng, Integer, Long, Byte等.
    还有BigDecimal,BigInteger等.对于这些对象是不需要线程同步保护的.因为它们的值不会被修改.