在java中 为什么申明的字符串   1、String a="abcd";
             在if(a=="abcd")
             这个成立。
               2、但是如果是用 String a= new String("abcd");
             在if(a=="abcd")
             就不成立了。
 我看到书上解释的是,==  是检查两个数是不是指向同一个对象,
                     equals();是检查的构成两个操作数的内容是否相同。
现在我想明白的是,1、直接赋值 和 2、new 后赋值 它们对象会改变,那是怎么改变的呢?那到底具体什么时候应该用2、new 赋值好,什么时候直接用1、赋值好呢?

解决方案 »

  1.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【sai_show】截止到2008-07-15 00:32:54的历史汇总数据(不包括此帖):
    发帖的总数量:3                        发帖的总分数:90                       每贴平均分数:30                       
    回帖的总数量:3                        得分贴总数量:0                        回帖的得分率:0%                       
    结贴的总数量:3                        结贴的总分数:90                       
    无满意结贴数:0                        无满意结贴分:0                        
    未结的帖子数:0                        未结的总分数:0                        
    结贴的百分比:100.00%               结分的百分比:100.00%                  
    无满意结贴率:0.00  %               无满意结分率:0.00  %                  
    敬礼!
      

  2.   

    new String("abcd");会创建一个新对象。而String a="abcd"不会。
    最好不要用new String 这种语法。
      

  3.   

    .....
    也不能说String a="abcd"没有创建对象,"abcd"是对象池中的,如果对象池中没有才创建。
      

  4.   

    http://topic.csdn.net/u/20080107/16/d176d162-e179-4303-b945-ada5cb1cba05.html
      

  5.   

    String a="abcd";
    String b="abcd";
    a和b其实是指向同一个对象,所以==为true。
    而用new方法得到的是在堆上的不同对象。所以==判断为false;但是equals方法得到结果为true。
    可以写个简单的例子测试一下。
      

  6.   

    大部分情况下使用直接赋值就可以了,没有必要new,效率应该会好一些。
      

  7.   

    问"ZangXT"我在孙鑫的教学视频上也提到了 “堆” 
    想请ZangXT  还能比较具体点讲解下 这个 “堆” 具体点的概念,或者说 “堆”是个什么样的概念,我个人觉得是否它也是针对于 内存空间来定义的内容!!
      

  8.   

    我写了一个简单的例子测试了一下,这样看起来可能比较清楚 :public class Test{
        public static void main(String[] args) {
            String a=new String("abc");
            String b="abc";
            String c="abc";
            
            System.out.println(a);
            System.out.println(b);
            System.out.println(c);
        }
    }它对应的虚拟机指令是:Compiled from "Test.java"
    public class Test extends java.lang.Object{
    public Test();
      Code:
       0: aload_0
       1: invokespecial #1; //Method java/lang/Object."<init>":()V
       4: returnpublic static void main(java.lang.String[]);
      Code:
       0: new #2; //class java/lang/String
       3: dup
       4: ldc #3; //String abc
       6: invokespecial #4; //Method java/lang/String."<init>":(Ljava/lang/String;)V
       9: astore_1
       10: ldc #3; //String abc
       12: astore_2
       13: ldc #3; //String abc
       15: astore_3
       16: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
       19: aload_1
       20: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       23: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
       26: aload_2
       27: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       30: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
       33: aload_3
       34: invokevirtual #6; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       37: return}从中可以看到,三个对象都是通过ldc #3得到的。对于new的String对象,先执行  0: new #2; //class java/lang/String
       3: dup
    两条指令,而其他两个直接赋值的对象都是直接加载常量区的字符串“abc”了
      

  9.   

    堆和栈相区别,它们都是存放数据的地方,栈中的数据后进先出,比如方法中的一些基本变量(不是通过new来创建的)他们在方法执行完毕之后就直接消失了,存取速度也比较快,这是栈的特点。堆中存放的是动态创建的对象,是通过new得到的。当不使用的时候有jvm负责回收。
    Object o=new Object();
    是在堆中创建一个实际的Object()对象,变量o是对该对象的引用,但o存在于栈上,当出了当前作用域之后o就不存在了,但堆中的该对象还存在。
      

  10.   

    继续问"ZangXT" :
    通过你9楼的介绍,我是否可以这样理解:
    Object o=new Object();
    这个是一个声明并实例化对象的表达,其实这个里面  真正所谓的对象是 Object();  而o 只是个代替Object();进行具体操作的变量,
    而且 Object();和 o   是在不同的内存空间中? 
    我这样理解对吗?
      

  11.   

    基本正确,不过堆里面只是一个Object对象,而不能说是Object(),理解区别就行了,毕竟表示的话还是需要用o来代替的。
      

  12.   


    那这样说来 在堆里面创建的Object对象是个抽象的,它在内存分配了空间, 那当他的变量o进行具体操作的时候  操作的数据交换到底是在 Object这个对象所在的堆这个空间进行的呢? 还是在o这个对象变量的栈空间里面进行的呢?
      

  13.   

    比如我用o.method()的方法,这个方法修改Object对象中的某个成员的值,他就是把堆上的这个对象中的相应数据修改了。
    比如
    StringBuffer buffer=new StringBuffer("hello ");
    buffer.append("world");开始在堆上创建一个StringBuilder对象,它的内容是hello ;buffer存在于栈中,它保存了对该对象的引用。
    buffer.append("world")之后,堆中他引用的对象的数据就变成了hello world;
    如果你再让buffer=new StringBuilder("test");
    这是buffer就指向了堆中的另一个对象,它的数据是test。但原来数据为"hello world"的对象让然存在于堆中,只不过现在没法引用到它了,java虚拟机会在适当的时候自动回收它的内存空间。
      

  14.   

    这样说来, 对象变量o,只是在栈内存空间中存在,这个空间里面所保存的就是对象名字o,当o进行具体操作的时候,所有对象的方法,属性发生改变后的数据都是在对象Object的堆空间里。 但是此时 再创建个Object b=new Object(); 对象的时候,堆里面划分了空间保存了这个新的对象,那在栈中是又划分了个新的空间保存了对象变量 b,  此时o和b  是在一个栈里面 但是没再同一个内存空间吧!