两个Sing类型可以比较吗   "0"=="0"
突然看到的一段代码 !!求高手指点下   

解决方案 »

  1.   

    怎么就不能比?你上面就等于
    String a = "a";
    String b = "a";
    System.out.println(a == b);
    他们比较的还是内存,只是a和b指向的是同一个内存,这里有个内存池的概念,在第一次String a = "a";的时候在内存池会分配一个a;第二次String b = "a";会先在内存池里找一个有没有"a"的,如果有a,b都去指向“a”
      

  2.   

    关于 String pool 的讲解网上有很多,楼主一搜就搜到。
      

  3.   

    是可以比较的,但绝对不建议楼主这样做。这样比较的是内存地址,这样以来,比较的结果很大程度上依赖于JVM的实现,虽然现在比较起来是相等的,但说不准在下一个版本里可能就不相等了(虽然这种可能性很小)。
      

  4.   

     == 比较的是地址
    String比较应该用equals()
      

  5.   

    本来这类问题不想回答了
    看还是有很多人认识上有误区,所以再次简单的说明一下
    ==和equals比较的都是的两个内存空间的信息
    ==比较的是直接内存空间的信息(即变量本身的内存信息),equals比较的间接内存空间的信息(即对象本身的内存信息)首先要清楚“内存空间”,一个变量,本身有自己的内存空间,==就是比较两个变量本身的内存空间的信息,所以是“直接内存空间”,也就是变量本身的内存空间
    比如
    int a = 1; int b = 1; a==b,比较的是变量a内存的和变量b内存的信息
    即a变量的内存信息的是 00000000 00000000 00000000 00000001 (二进制4个byte)
    b变量的内存信息是是 00000000 00000000 00000000 00000001 (二进制4个byte)
    因为a和b的内存信息一样,所以==是trueequals比较的是变量所引用的对象的内存空间的信息,即不是直接比较两个变量的内存空间的信息,而是比较两个变量所引用的对象的内存空间的信息,所以是“间接内存空间”,也就是对象本身的内存空间而不是变量自身的内存空间
    比如
    String a = "a"; String b = new String("a");
    ==比较的是变量a的内存和变量b的内存信息,变量a和b的内存空间里存放的是对象的地址
    即a变量的内存是 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx (二进制4个byte "a"对象的地址)
    b变量的内村信息是 yyyyyyyy yyyyyyyy yyyyyyyy yyyyyyyy (二进制4个byte,new String("a")对象的地址)
    很显然,在这个例子里a的内存信息和b的内存信息不一样,也就是a和b引用的对象不一样,所以a==b是false
    而eqauls比较的是对象的内存空间信息,
    "a"对象的内存地址是 xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx (也就是a变量的内存信息)
    该内存地址保存的是00000000 00000061 ('a'字符的ascii码)
    同样的new String("a")对象的内存地址是 yyyyyyyy yyyyyyyy yyyyyyyy yyyyyyyy (也就是b变量的内存信息)
    该内村地址保存的是 00000000 00000061 ('a'字符的ascii码)
    equals比较的是"a"对象和new String("a")对象的内存信息,所以a.equals(b)是true,因为对象的内存信息都是字符'a'的ascii码
    可见,a和b两个变量所引用的对象虽然不同,既对象的地址不同,但是对象的内存信息相同,所以a==b是false(两个变量的内存信息不同),a.equals(b)是true(两个对象的内存信息相同)所以,==比较的是变量的内存信息(直接内存比较),eqauls比较的对象的内存信息(间接内存比较)
    因为引用类型的变量的内存信息是对象的地址,所以简单的说==是比较地址,equals是比较内容
    但是要清楚,==比较的变量本身的内存信息,equals比较的变量所引用的对象的内存信息
    在这点上,学过C/C++的人(了解指针概念的人)都会比较好容易理解
      

  6.   


    小弟冒昧问下,我记得我当初学的时候记得时,看源码equals等同于==,之所以String特别,是因为String重写了equals方法,所以会和==不同,小弟才疏学浅,也不知对不对,有点疑惑了
      

  7.   

    朋友,你看的是Object这个类吧,你去看看String或者其他的什么类,Object这个类的equals确实是==一样效果,其他的类要重写equals的,所以你自己写的一个类要重写equals这个方法,就是这个原因
      

  8.   


    我是这个意思啊,只是看八楼说的,只是适用于String,如果String没有重写equals方法,就和==一样了吧
      

  9.   

    对的,如果没有重写equals等于就是Object的equals,而Object的equals和==一样的,比较的是内存地址
      

  10.   

    我在这里说的equals是针对String的,equals是方法,怎么比较完全可以由用户重写而决定
    只是因为很多人都说==是比较“地址”,却不知道这个所谓的比较“地址”是什么意思
    所以想说明一下,==其实是比较两个变量的内存信息,equals是比较对象的内存信息(因为equals可以重写,所以要比较对象的什么信息可以由用户重写equals方法决定,不管怎么重写,目的都是为了希望对象的某些内存信息一样我们就认为是相同的)
      

  11.   

    http://www.ticmy.com/?p=186http://www.iteye.com/topic/774673
      

  12.   

    简单的说吧,==比较的是堆内存中对象内存地址是否一样,equals方法则是比较对象像不像,至于像的标准只是由你来确定的。
      打个比方,1.一对双胞胎如果用==号则是说他们2个是不是一个人,很明显2个人不可能是一个人。
                2.equals方法则是说,他们长的是不是一样,这个就看观看者怎么看了,每个人可以有自己的方法,观点(相当于重写equals方法)在这个层面上,我们只是说尽量保持equals的2个对象里面的内容保持一致。
      

  13.   

    我来补充一下这个师兄的回答 楼主可以再去了解一下  == 与equals 的区别。
    我当时也是这个师兄给我讲懂的哦。 
      

  14.   

    ==比较的是引用对象之间的相等关系
    equals比较的是值对象之间的相等关系String类是值对象,不可变对象,用equals来比较
      

  15.   

    17楼说的是对的。8个原生数据类型创建出来后,每个变量都会分配一个新的内存地址,没有想String类的“字符串池”的概念,如果也是比较内存地址,那两个值相同的基本数据类型比较,结果不就成了false了吗?
      

  16.   

    你没看我在1楼的解释?指向的是同一个内存int a = 1;int b = 1;就相当于String a = "1";String b = "1";你去试试字符串的a==b看看返回的是什么,别误导别个哦
      

  17.   

    public void show()
    {
    String s1="a";
    //LDC "a" 加载字符串常量到操作数栈
    //ASTORE 1 保存字符串常量到变量s1
    String s2=s1+"b";//这里调用StringBuffer操作并创建一个String对象
    //NEW java/lang/StringBuffer 创建StringBuffer对象
       // DUP 复制StringBuffer对象
       // ALOAD 1 加载字符变量s1到操作数栈
       // INVOKESTATIC java/lang/String.valueOf (Ljava/lang/Object;)Ljava/lang/String;调用String的静态方法valueOf
       // INVOKESPECIAL java/lang/StringBuffer.<init> (Ljava/lang/String;)V 调用StringBuffer的构造函数
       // LDC "b"加载字符串常量“b”到操作数栈
       // INVOKEVIRTUAL java/lang/StringBuffer.append (Ljava/lang/String;)Ljava/lang/StringBuffer;调用SringBuffer的append方法追加字符串“b”
       // INVOKEVIRTUAL java/lang/StringBuffer.toString ()Ljava/lang/String;调用StringBuffer的toString方法
       // ASTORE 2保存字符串对象到s2变量中
    String s3=new String("ab");
    //NEW java/lang/String创建String对象
       // DUP复制String对象
       // LDC "ab"加载字符串常量到操作数栈
       // INVOKESPECIAL java/lang/String.<init> (Ljava/lang/String;)V调用String的构造函数
       // ASTORE 3保存String对象到变量s3中
    String s4=s3+"c";//这里调用StringBuffer操作并创建一个String对象
    //NEW java/lang/StringBuffer创建StirngBuffer对象
       // DUP复制StringBuffer对象
       // ALOAD 3加载变量s3
       // INVOKESTATIC java/lang/String.valueOf (Ljava/lang/Object;)Ljava/lang/String;调用String的静态方法valueOf
       // INVOKESPECIAL java/lang/StringBuffer.<init> (Ljava/lang/String;)V调用StringBuffer的构造函数
       // LDC "c"加载字符串常量到操作数栈
       // INVOKEVIRTUAL java/lang/StringBuffer.append (Ljava/lang/String;)Ljava/lang/StringBuffer;调用SringBuffer的append方法追加字符串“c”
       // INVOKEVIRTUAL java/lang/StringBuffer.toString ()Ljava/lang/String;调用StringBuffer的toString方法
       // ASTORE 4保存字符串对象到s4变量中
                System.out.println("ab"==s2);//结果是false,"ab"是字符串常量而s2是String在堆中的对象所以为false
                System.out.println(s2+"c"==s4);//结果是false,s2+"c"将产生一个String对象到堆中而s4本身是堆中的一个对象,所以两个对象比较为false
    } 通过以上的class指令分析知道:String s2=s1+"b";//是调用stringBuffer操作并创建一个String对象也就是说+操作符使用StringBuffer的append方式实现的最后返回一个新创建的String对象而不是string常量。"a"+"b"等价于"ab",只是生成一个字符串常量,保存在栈中而String s2=s1+"b";保存在堆中。凡是字符串变量与字符串变量或者字符串常量之间使用+都会产生一个String对象到堆中,凡是String s="a"+"b";或者String s="ab";产生一个字符串常量在栈中。
      

  18.   

    == 比较 内存地址
    equals 比较值.
      

  19.   

    == 适用于数值,布尔,和内存地址之间的比较;
    如果是字符串的比较建议用equals;
      

  20.   

    == 比较 内存地址
    equals 比较值
      

  21.   

    ==是比较内存地址吗?
    int a=1;int b=1;
    a和b的地址是一样的吗?
      

  22.   

    没有new关键字,在加上内存池的概念,你看看是不是相同的
      

  23.   


    你说的是不对的。你可以自己对照内存想想。原生类型和引用类型你不能一概而论。String a ="1";
    String b = "1";引用a,引用b.他们在栈中的地址是不一样的。但是他们地址中的内容是一样的,也就是他们指向的是同一对象。所以对于引用类型做==的时候,比较的是他们所指向的对象在内存中的地址是不是一样的。换句话说,指向的是不是同一个对象。对于原生类型。int a = 1;
    int b = 1;a和b在JVM栈中的地址是不一样的。而地址中的值是一样的都是1.所以a == b为真。显而易见,比较的值。而非你所说的地址。如果非要下个总结的话。因为不一定都在栈中,所以话不太好说。就用C来描述吧。pa = &a ;pb = &b;比较的是 *pa和*pb对于引用来说,*pa.就是他所指向对象的地址。
    对于原生类型来说,*pa就是他的值。
      

  24.   

    刚好你画出来了,那你给我解释下String a="1";String b="1";为啥一样?比较的值?你只画了栈和堆,还少了一个数据域,堆里的那个东西指向的是数据域,堆的那个是个引用,真正的值在数据域里面
      

  25.   

    我知道,你所说的数据域。无非就是,堆中方法区的,运行时常量池。我想告诉你的是,原生数据类型,比的不是地址。String的那个东西,大家都知道你就不用解释了。原生数据类型,基础数据类型。明白?
      

  26.   

    String的那个东西,大家都明白。给你纠正的是,基本数据类型比较的是值,而非地址。
      

  27.   

    或者,你执意觉得自己上面说的对。那么你就告诉我public static void main(String[] args){
         int a;
         int b;
    }
     他俩的地址能一样吗?
      

  28.   

    那你们看看http://sd.csdn.net/a/20120629/2806999.html,中的第四小节
      

  29.   

    可以比较
    ==是比较两个所指向的对象是否相同;
    equal 是比较两个变量所指向的对象内容是否相同。
      

  30.   


    你那篇文章我看了,但我感觉那上面说的也欠妥。其实,编译出的字节码就一切可知了。对比一下(1)创建对象public class Test{
    public static void main(String[] args){
    Cute c = new Cute();
    }}看一下与之对应的字节码
      public static void main(java.lang.String[] args);
        0  new Cute [16] 
        3  dup
        4  invokespecial Cute() [18]
        7  astore_1 [c] 
        8  return(2)String 常量值public class Test{
    public static void main(String[] args){
    String str = "abc";
    String strr = "eee";
    String strrr = "abc";
    }}
      public static void main(java.lang.String[] args);
         0  ldc <String "abc"> [16]
         2  astore_1 [str]
         3  ldc <String "eee"> [18]
         5  astore_2 [strr]
         6  ldc <String "abc"> [16]
         8  astore_3 [strrr]
         9  return
    (3)基本数据类型public class Test{
    public static void main(String[] args){
    int a = 5;
    int b = 5;
    }}  public static void main(java.lang.String[] args);
        0  iconst_5
        1  istore_1 [a]
        2  iconst_5
        3  istore_2 [b]
        4  return以比较局部的角度来看,那么只有(1)(2)与堆内存发生了关系。
    (3)没有。而且,istore ,astore.足以说明,我们的引用和基本类型里面存的是什么。而且,(3)没有与常量池发生关系。不知道你满意吗?
      

  31.   

    这个第四部分是纯扯淡的。
    http://topic.csdn.net/u/20081123/12/f70f1632-24be-4caa-bc20-29cf8267afab.html?36468在13楼有分析。原始帖子的传播很有意思:新手总结->其他新手认可->传播->一传十十传百->哇塞,真理啊!
    其中还有几本书把“java 栈和堆”抄了进去,总之各种给力。
      

  32.   

    对于引用数据类型一般都是用equals(), 基本数据类型用 == 
    参考地址:http://www.zousky.com/rjkf/java/javase/
      

  33.   

    两个字符串相比较  可以的  返回true or false
      

  34.   

    两个String类型是可以使用==比较的,如果要比较两个String类型的对象,建议使用equals()方法来比较,详情请参阅java源码