例如:
String s="xx.jpg";
s=substring(2);
String str1=".jpg";
String str2=".jpg";
用==比较:
str1==str2//结果true
str1==s//结果false如果理解为对象str2找到了字符串池中有",jpg"中这个实体,所以它直接指向这个实体,所以str1==str2//结果true
但s在执行了s=substring(2),它对应的实体也是".jpg";为什么str1没有直接指向这个实体呢?String类型的变量空间究竟是怎样非配的呢?请教!!

解决方案 »

  1.   

    substring(2)这函数不是这么用的吧??
    substring(1,4)该这么用吧??
      

  2.   

    以下是String的源代码!
    public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > count) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    if (beginIndex > endIndex) {
        throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
    }
    return ((beginIndex == 0) && (endIndex == count)) ? this :
        new String(offset + beginIndex, endIndex - beginIndex, value);
        }可见str1==s//结果false !
      

  3.   

    Java 中 字符串的"==" 是看引用是不是同一个.
    而真正的内容是不是相等是用equalsstring s1=new String("Hello"); 
    string s2=new String("Hello"); 
    则(s1==s2)=false 如果: 
    string s1="Hello"; 
    string s2="Hello"; 
    则(s1==s2)=true; 
    因为他们指向的同一个对象。 如果把其他变量的值赋给s1和s2,即使内容相同,由于不是指向同一个对象,也会返回false。
    所以建议使用equals(),因为equals比较的才是真正的内容 
      

  4.   

    String s=new String("abc");
    String ss="abc";
    s==ss//false;
    ss="abc";//这种称之为字面量,而第一种的则不是.字面量和普通的对象内存地址是不一样的,所以为false,s=substring(2);生成的以不是字面量了.所以有了你所看到的结果.
      

  5.   

    回1楼:substring(2)是从下标为二的到字符串末尾,见JAVA API
      

  6.   

    一步一步分析:
    首先,String类是不可变的字符序列。
    String s = "xx.jpg";
    这个时候在字data segment中分配了一个字符串空间,里面装的是"xx.jpg",s指向它。
    s = substring(2); //用到了public String substring(int beginIndex)这个方法,从字符串下标为2的地方开始截取,相当于又再data segment中分配了块空间,里面装的是你截取后的字串,是".jpg",然后把s的引用指向它。String str1 = ".jpg";
    这个时候在data segment中开辟了块空间,里面装的是".jpg",stack里的变量str1指向它。
    当你再String str2 = ".jpg";的时候,又在stack上分配了个变量str2,也指向".jpg",所以,比较s1==s2的结果是true.当你比较str1==s的时候,很明显它们指向的不是同一块空间。分かりましたか?
      

  7.   

    String类型属于引用类型,他在内存中的存储方式有些特别(所有应用类型的数据都是这样的)。
    内存空间分为“栈内存”和“堆内存”,引用数据类型存储时被分成的两部分分别存储在“栈内存”和“堆内存”中,举个例子:
    String a="12345";等号的右边String a只是声明了一个变量a,a中所存放的只是"12345"这个字符串的地址,也就是我们平常说的句柄,这个句柄是被存放在“栈内存”中的,而"12345"这个对象本身会存放在“堆内存”中的一片连续的空间中,你这样写"str1==s"实际上是比较两个对象的地址是否相同,并不是比较对象的内容是否相同。
    看到这先别急着问问题,你会说str1==str2比较的也是句柄为什么结果是true呢?当你用String str1=".jpg";String str2=".jpg"; 这种形式给String类型变量直接赋值时,系统会把".jpg"这个字符串作为一个常量放在内存的缓冲区中,无论哪个变量用到它都会把同一个地址赋给那个变量,如果你这样写:“String str1=new String(".jpg");String str2=new String(".jpg"); ”比较的结果就不一样了。
      

  8.   

    str1==str2,比较的是同一个地址值,故结果是true
    str1==s,比较的是不同的地址值,故结果是false
    以上都是对象的引用在比较
    另外,回3l,equalse是用==实现的,他们的结果一样,除非覆盖equalse方法
      

  9.   

    3L说的没错啊,String类已经重写了equals方法,所以可以直接拿来比较其中的内容
      

  10.   


    8楼有错 ; 字符串常量是 存在 date segment并不是   栈内存”“堆内存 ;
    new 出来的东西在 堆内存;
    你实际上是拿一个在   堆内存的地址 和一个在date segment的 地址比较
    当然不相等    我估计是这样
    Kimi-赵龙日-大连    拜托你说明白些好吗?
      

  11.   

    答:呵呵,你还要Kimi说明白些什么呢?告诉你年龄。。吗?
    呵呵。。
      

  12.   

    字符串比较内容的使用equals方法。但是比较内存地址的话使用==。上面的s是由别的变量截取过来的。s指向的是一个内存地址。s属于间接赋值 。而str1和str2是直接赋值的,且字符串内容相同。所以 为true。str1和s指向的内存地址不同,所以==的时候是false。如果用equals比较的话,他们都是true。
      

  13.   

    字符串的比较用equals,不要用==,含义是不同的,这种问题讨论的太多了
      

  14.   

    我还是没有看太明白.
    拜托能把字符串空间分配这块将清楚点。
    分配的空间什么时候是在堆里分配?什么时候时候是在栈里分配?
    我也知道字符串里内容比较是用equals比较。
    就上面问题,继续请教。
    谢谢
      

  15.   

    系统对所有的字符串常量和常值的String表达式都会自动地进行字符串扣留。
    只有包含变量的String表达式需要显示的调用intern()进行扣留。
    String s="xx.jpg"; 
    s=substring(2);     //包含变量的String表达式
    String str1=".jpg"; //字符串常量常值的String表达式(*自动地进行字符串扣留intern()
    String str2=".jpg"; //字符串常量常值的String表达式(*自动地进行字符串扣留intern()所以
    str1==str2//结果true 
    str1==s//结果false 如果改变 s=substring(2).intern(); //*显示的调用intern()进行扣留 
    则结果会发生变化 
    str1==str2//结果true 
    str1==s//结果true 唉,为什么不好好看书呢...
      

  16.   

    String类确实提供了subString(int beginIndex)这个方法,另外一个是subString(int begin,int end),这是使用了重载技术;
    subString方法会根据指定的下标截取字符串,在堆内存中生成一个新的对象并将引用返回。
    而使用String str1="字符串A"这种方法,第一个是在内存中构建一个String对象,并将引用赋给str;如果之后又有String str2="字符串A",则会在内存中寻找到先前构建的"字符串A"并将其引用赋给str2。所以通过(str1==str2)这中方法判断结果是true。记得某本外国有关Java方面的著作是这么讲的。