2个String对象到底是怎么判断是否 == 的?String s3 = "fff";
  String s4 = "fff";
           System.out.println(s3 == s4);
    这个结果是true,我的理解是这种写法在栈空间里s3和s4其实都是指向堆空间里的“fff”,所以s3就是等于s4的,比较的是他们栈空间的编码,所以相等但是
String s = new String("fff");
String s2 = new String("fff");
           System.out.println(s == s2);这样写的话结果就是false,相当于这二个引用虽然都是“fff”,但是指向的其实是堆空间里的2块内存,所以就造成了他们不==,但是我又不理解在这里比较的是什么值?因为我打印以上s1,s2,s3,s4的hashCode,发现都是一样的“101286”看了下api文档,String重写了hashCode()方法
返回此字符串的哈希码。String 对象的哈希码按下列公式计算: 
 s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
 使用 int 算法,这里 s[i] 是字符串的第 i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希码为 0。) 那既然所有的“fff”都是一样的hash码,为什么通过new的方式就不等?直接写的方式就等呢?其实也不是什么大的问题,就是搞不明白,有点纠结

解决方案 »

  1.   

    你的问题不是一两句话可以说明白的,太混乱了,==判断的是两个对象的地址是否相同,跟hasCode一点关系都没有。
      

  2.   

    ==不是比较的hashCode,表示的是否引用同一个对象
      

  3.   

    == 表示同一个对象,这里相等是因为Java编译器会优化处理它们,多个类中的相同字符串也会由JVM加载器时优化减少重复字符串
      

  4.   

    ==是比较是不是在同一地址,new了2个肯定不在同一地址
      

  5.   

    String s3 = "fff";这个赋值给的是 "fff"的地址引用,所以s3的内容 是内存空间地址,s4 也是地址,而且两个地址是一样的如果使用new 构造的话,s 和 s2 地址是不一样,自然内容也不一样了
      

  6.   

    就题而论:
    s3==s4
    s==s2
    是检测两个对象的引用是不是指向同一个对象,如果指向同一个对象就返回true,如果不是就返回false.
      

  7.   

    String s3 = "fff";
    String s4 = "fff";
    System.out.println(s3 == s4);s3和s4是栈内变量,有自己的内存,它们的内存保存的是常量字符串"fff"的地址
    ==比较的s3和s4变量自身的内存的内容,都是"fff"的地址,所以trueString s = new String("fff");
    String s2 = new String("fff");
    System.out.println(s == s2);
    s和s2是栈内变量,有自己的内存,它们的内存分别保存new String("fff")对象的地址,两个new出来的对象不是同一对象,在堆中有自己的内存地址
    ==比较的s和s2变量自身的内存的内容,分别是两个new出来的对象的地址,所以不同,即false
      

  8.   

     我目前了解的是字符串的hash码计算方式是按照字符串的值来进行计算的,不是按内存地址,别的hash码好像大部分都是按内存地址算的。
     String s3 = "fff";这种写法,字符串放进了常量池中。由于这里fff是第一次出现,常量池中没有“fff”,就在里面创建了一个“fff”。之后String s4 = "fff";这回因为常量池中已经有了“fff”,所以s4就指向了和s3一样的地址。所以“==”为true。
     new 出来的String是在堆中,String s = new String("fff");你可以换个写法来理解A s = new A("fff");相当于创建了一个A的对象,并给“name”属性赋值为“fff”,所以上面你相当于创建了两个具有相同“name”属性的对象,因为是两个对象,内存地址不一样,所以“==”为false。
     字符串确实有点复杂和奇怪下面几种形式是我在书上抄的,与大家一起学习,有理解透彻的达人们可以给讲讲,一起进步。
    String hello="Hello";
    String lo="lo";
    System.out.println(hello=="Hello");  
    //true  相同包中相同类内的字符串值表示引用相同的String对象
    System.out.println(Other.hello==hello); 
    //true 相同包中不同类内的字符串值表示引用相同的String对象
    System.out.println(other.Other.hello==hello); 
    //true 不同包中不同类内的字符串值也表示引用相同的String对象
    System.out.println(hello=="Hel"+"lo"); 
    //true 通过常量表达式计算的字符串是在编译时计算的,然后将它们视为值
    System.out.println(hello=="Hel"+lo); 
    //false 通过串联在运行时计算的字符串的是最新创建的,因此是截然不同的
    System.out.println(hello==("Hel"+lo).intern());
    //true 显式限定计算过的字符串所带来的结果是:与任何预先存在的字符串值相同的字符串具有相同的内容
      

  9.   

    equals比较的事hashcode,==比较的是指向对象地址
      

  10.   

    嗯  学习学习
    ==与hashcode无关吧 直接比较地址
      

  11.   

    1、==不是比较的hashCode,==判断的是两个对象的地址是否相同,String s3 = "fff";
    String s4 = "fff";
    这样定义字符串的方式,是指s3和s4同放在一个字符串堆空间,此时两者的地址是相同的,所以用==的话,返回为true。
    2、String s = new String("fff");
            String s2 = new String("fff");
               System.out.println(s == s2);
    这种方式是s和s2为两个不同的引用、占用不同的内存块,当然他们的首地址也不相同,所以毫无疑问,用==比较,返回为false。
      

  12.   

    ==是比较的内存地址,equals()比较值
      

  13.   

    ==直接比较地址,应该和hashcode()无关吧
      

  14.   

    楼主明白java数据在内存中的储存方式吗?(内存里面主要分成四个区:1、Code Segment:储存代码;2、Data Segment:储存静态变量和字符常量;3、Stack:储存临时变量;4、Heap:储存new出来的对象)所以在第一个例子里,"fff"是字符常量,存储在Data Segment,在内存中只有一份,两个引用指向同一块内存,所以地址相同;
    在第二个例子里,两个对象都是new出来的,存储在Heap区,两个引用指向不同的对象,也就是不同的内存块,所以地址不相同。
      

  15.   

    简单来说,java中的string如果是直接赋值的话,两个对象的指向同一个地址内存,故返回true
    当new一个string对象时,对象的内存地址就不一样了,故返回false