public class StringTest {
private static String a="abcdef";
/**
 * @param args
 */
public static void main(String[] args) {
// TODO Auto-generated method stub
String s1="abc"+"def";
String s2="abc";
String s3="def";
String s4="abcdef";
System.out.println(s1==a);
System.out.println(s1==s4);
System.out.println((s2+s3)==a);
System.out.println((s2+s3)==s4);
}
}
结果是什么:为什么

解决方案 »

  1.   

    大概估計一下: 應該是true,true,false,false.
    1.因為S1,a,S4都是指向堆棧中的“abcdef”,所以他們地址指向是一致的.所以前兩個為true。
    2.s2和s3也是指向堆棧,但是他們合併時,會創建一個對象用來保存結果的,所以他們相加指向的並不是堆棧中的地址,而是內存當中的,所以後兩個為false。
      

  2.   

    true
    true
    true
    true
    你输出一下就知道了
      

  3.   


    Each string literal is a reference (§4.3) to an instance (§4.3.1, §12.5) of class String (§4.3.3). String objects have a constant value. String literals—or, more generally, strings that are the values of constant expressions (§15.28)—are "interned" so as to share unique instances, using the method String.intern.Thus, the test program consisting of the compilation unit (§7.3):
        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"; }
    and the compilation unit:
        package other;    public class Other { static String hello = "Hello"; }
    produces the output:
        true true true true false true
    This example illustrates six points:Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1).Literal strings within different classes in the same package represent references to the same String object.Literal strings within different classes in different packages likewise represent references to the same String object.Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.Strings computed by concatenation at run time are newly created and therefore distinct.The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents....
      

  4.   

    "abcdef"是在串池中(堆中),S1 a S4 都是指向该处 ,故前两个是true
    s2 s3 是分别指向堆中某处,各自利用串池中的 "abc" 和 "def"创建了一个对象
    当 s2 + s3 时返回的是新建的一个对象, 该对象利用串池的"abcdef"创建对象
    但和串池中的那个并不是同一个
    故后两个都是false
      

  5.   

    全部为TRUE这些应该叫编译时常量!运行前就已经被优化了!
      

  6.   

    操作符“+”会产生一个新的字符串:
    详见帖子:
    http://topic.csdn.net/u/20080415/12/3f2b9589-e97c-4129-8941-011bd9203a98.html
      

  7.   

    String类用到了不变模式,a、s1、s4都是"abcdefg",他们会指向同一个new ("abcdefg")对象
    (s2+s3)是临时的变量
      

  8.   

    竟然是:true
    true
    false
    false我以为全是true! 看来,s2+s3 new 了新对象了! 
      

  9.   

    true
    true
    false
    false
    涉及到String常量池。通过String s = "abcdef" ; 来定义s时,在池中放入abcdef,是一个整体。
    String s1 = "abc" ;
    String s2 = "def" ;
    String s3 = s1 + s2 ;
    首先在池中会有s1和s2,定义s3时,s1和s2是变量,会在池中另辟内存给s3。String s4 = "abc" + "def",首先计算右边的表达式,结果为temp,然后在池中找,如果有temp字符串,s3就指向temp(就是那个s);如果没有的话就和String s = "abcdef" ;是一样的效果。
      

  10.   

    true
    true
    false
    false
    有关字符串池的内容,字符串池的定义是:在该字符串池中,具有相同的字符序列的字符串只对应一个字符串实例对象。a和s4是字符串直接变量,所以是指向的同一个实例对象。而s1虽然不是字符串直接变量,但是其是由有限个字符串通过“+”运算的结果,所以s1指向的字符串位于字符串池中,所以a和s1指向的字符串具有相同的字符序列。
    对于((s2+s3) == a),虽然变量s2和s3指向的是一个字符串直接量,但变量s2和s3本身不是字符串直接变量,所以(s2+s3)不在字符串池中。
      

  11.   

    public class StringTest {
    private static String a="abcdef";
    /**
    * @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s1="abc"+"def";
    String s2="abc";
    String s3="def";
    String s4="abcdef";
    System.out.println(s1==a);
    System.out.println(s1==s4);
    System.out.println((s2+s3)==a);
    System.out.println((s2+s3)==s4);
    }
    }
    结果是什么:为什么
    在这个程序中用到了String池的概念。如果是这样声明的:
    String s = "abc" 则s是位于String池中,而不是像new出来的对象位于heap中,
    当用一个对象+对象 或者是对象+ 位于String池中的String时,会产生一个新的对象,所以
    System.out.println(s1==a); 结果为true因为都是位于String池。
    System.out.println(s1==s4);结果为true,原因同上。
    System.out.println((s2+s3)==a);
    System.out.println((s2+s3)==s4); 这2个则是因为产生新的对象在heap中,而a和s4是位于String池的。所以为false;
      

  12.   

    加来加去都是true,因为这些都是放在常量池里
    abc+def  首先在常量池创建abc 然后再创建def,最后相加创建abcdef
    而最后呢都是指向同一处,都是指向常量池的那个abcdef
    LZ明白没
      

  13.   

    其中归根结底
    public class StringTest3 { /**
     * @param args
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s1 = "abc" + "def";
    String s2 = "abc";
    String s3 = "def";
    String s4 = s2 + s3;
    System.out.println(s1 == s4);
    System.out.println(s1 == "abcdef");
    System.out.println(s4 == "abcdef"); }
    }
    就是s1,s4不一样。
      

  14.   

    这样做有啥意义哦?字符串是一个对象,对象值之间的比较应该使用 equals 方法!
      

  15.   

    == 比较的是指向
    equests 比较的是 值
      

  16.   


    针对不同的类是不一样的,Object和String就不一样,应该写成“equals”
      

  17.   

    字符常量是在数据区中分配的,所以在堆中分配了一个字符创常量“abcdef”,a、s1、s2都是它的引用,所以前两个为true,s2+s3生成了一个新的String对象,所以后两个为false
      

  18.   

    找到答案 了:java中String问题,String a=new String(""); 和String a=new String();有区别吗
     悬赏分:10 - 解决时间:2009-7-2 18:52 
    a="aaaaa";
    String a=new String("aaaaa");有区别吗?
    和String a; a="aaaaa";
    有区别吗? 
    问题补充:请你说具体点好吗,谢谢咯~~提问者: decai_1 - 一级最佳答案详细的这儿有哇:解析Java中的String对象的数据类型  1. 首先String不属于8种基本数据类型,String是一个对象。  因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。  2. new String()和new String(“”)都是申明一个新的空字符串,是空串不是null;  3. String str=”kvill”;   String str=new String (“kvill”);的区别:  在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。  常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。  看例1:  String s0=”kvill”;  String s1=”kvill”;  String s2=”kv” + “ill”;  System.out.println( s0==s1 );  System.out.println( s0==s2 );  结果为:  true  true  首先,我们要知结果为道Java会确保一个字符串常量只有一个拷贝。  因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”kvill”的一个引用。  所以我们得出s0==s1==s2;  用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。  看例2:  String s0=”kvill”;  String s1=new String(”kvill”);  String s2=”kv” + new String(“ill”);  System.out.println( s0==s1 );  System.out.println( s0==s2 );  System.out.println( s1==s2 );  结果为:  false  false  false  例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。  4. String.intern():  再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了  例3:  String s0= “kvill”;  String s1=new String(”kvill”);
      
      String s2=new String(“kvill”);  System.out.println( s0==s1 );  System.out.println( “**********” );  s1.intern();  s2=s2.intern(); //把常量池中“kvill”的引用赋给s2  System.out.println( s0==s1);  System.out.println( s0==s1.intern() );  System.out.println( s0==s2 );  结果为:  false  **********  false //虽然执行了s1.intern(),但它的返回值没有赋给s1  true //说明s1.intern()返回的是常量池中”kvill”的引用  true
      
      最后我再破除一个错误的理解:  有人说,“使用String.intern()方法则可以将一个String类的保存到一个全局String表中,如果具有相同值的 Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把他说的这个全局的String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的:  看例4:  String s1=new String("kvill");  String s2=s1.intern();  System.out.println( s1==s1.intern() );  System.out.println( s1+" "+s2 );  System.out.println( s2==s1.intern() );  结果:  false  kvill kvill  true  在这个类中我们没有声名一个”kvill”常量,所以常量池中一开始是没有”kvill”的,当我们调用s1.intern()后就在常量池中新添加了一个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址注册到常量池中”了。  s1==s1.intern()为false说明原来的“kvill”仍然存在;  s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。  5. 关于equals()和==:  这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。  6. 关于String是不可变的  这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了,比如说:String str=”kv”+”ill”+” “+”ans”;  就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” “ 生成 ”kvill “存在内存中,最后又和生成了”kvill ans”;并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的。  21
      

  19.   

    《String in Java》 这个帖子关于String的总结,可以看看。private static String a="abcdef";
    /**
    * @param args
    */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    String s1="abc"+"def";
    String s2="abc";
    String s3="def";
    String s4="abcdef";
    System.out.println(s1==a);
    System.out.println(s1==s4);
    System.out.println((s2+s3)==a);
    System.out.println((s2+s3)==s4);
    }
    }    Java编译器对上面的代码编译的时候,对于String str="xxx"。这样的语句会创建常量池来存储"xxx"常量,并将"xxx"在常量池中的地址赋值给引用str。
        因此上面代码编译后的常量池存放了字符串常量"abc","def","abcdef"。(其中"abc"+"def"在编译阶段就会合并起来成为"abcdef")。假如这三个字符串常量在常量池中的地址是:Ox0001,Ox0002,Ox0003。 那么引用a、s1和s4存储的内容就是Ox0003, 而引用s2存储的是0x0001, s3存储的是0x0002。    “==”比较的是引用,因此a=s1=s4!=s2!=s3.     另外 s2+s3编译器会把它编译成这样两个语句:StringBuilder temp=new StringBuilder(s2),temp.append(s3).这样的话就会在堆中形成一个对象,而对象的引用是堆中的地址,自然不会和常量池中的地址相同了。
      

  20.   

    http://topic.csdn.net/u/20080415/12/3f2b9589-e97c-4129-8941-011bd9203a98.html
      

  21.   

    45楼的回答太精彩了,其实就是编译时STRING常量是放在常量区,并且2个常量相加也是常量。
    而+号(两端如果是变量)则会在堆中。
      

  22.   

    结果true,true,false,false
    String s1="abc"+"def";//等同于"abcdef"
    String s2="abc";//字符串常量
    String s3="def";//字符串常量
    String s4="abcdef";//字符串常量
    System.out.println(s1==a);//字符串常量比较
    System.out.println(s1==s4);//字符串常量比较
    System.out.println((s2+s3)==a);//s2+s3创建了一个新对象a是字符串常量结果当然为false
    System.out.println((s2+s3)==s4);//s2+s3创建了一个新对象s4是字符串常量结果当然为false你还是看看这个吧:
    http://blog.csdn.net/chenshuang_com/article/details/7743296