用String p=new("csdn")  创建一个对象和用 String p=("csdn") 声明一个变量有什么本质上的不同吗?譬如在如何存储上以及内存分配上

解决方案 »

  1.   

    用String p=new("csdn") 创建一个对象和用 String p=("csdn") 声明一个变量有什么本质上的不同吗?譬如在如何存储上以及内存分配上
    ------------------
    不知道你是不是想问String p = new String("csdn"); 跟 String p = "csdn";
    的区别呢?
    前者是在堆中创建一个String 对象,并返回其句柄(或者说引用)p。
    后者则先在堆中查询是否有"csdn"这样的对象,如果有,则返回该对象的句柄赋给p
    所以你会发现一下代码片段中:
    String p1 = "csdn";
    String p2 = new String("csdn");
    System.out.println(p1.equals(p1));
    System.out.println(p2.equals(p2));
    System.out.println(p1=="csdn");
    System.out.println(p2 == "csdn");输出为:
    true
    true
    true
    false
      

  2.   

    第一个是String对象,系统给他分配一块内存,而后者只是一个指向这块内存的引用,不知道这样说对不对,也是从CSDN听说的,等着挨批评
      

  3.   

    http://www.javaresearch.org/article/showarticle.jsp?column=546&thread=52728
      

  4.   

    String str = "welcome" 创建一个标准化字符
    String str2 = str.intern();其效果一样..
    String str3 = new String("welcome"); 创建一对象..
      

  5.   

    http://dollarhuang2005.spaces.msn.com/blog/cns!A83A17675EC2E0AA!116.entry
      

  6.   

    zhangdaj() 
    前者在堆中分配空间
    后者在常量区中分配空间
    学习中
      

  7.   

    坚决支持第二种写法。p = "csdn"; 
    强烈反对第一种写法。p = new String("csdn"); // <- 枪毙枪毙 x_x原因:
    第二种写法严重浪费系统资源。
    第一种写法会在内存中保存一个String类型的常量。无法被垃圾回收机制回收。
    第二种写法会在heap中动态开辟一块内存保存一个String类型的对象,可以被垃圾回收。但是在产生这个动态内存的同时,因为使用常量来定义(注意new String之后括号里面的东西),所以,与此同时同样会在内存中保存一个永不被回收的Strign类型常量。造成内存的重复浪费,同时new一个对象时的那不小的CPU开销和随后垃圾回收所用的资源也是白白浪费。综上,忘掉p = new String("csdn");这种垃圾写法吧。永远不要让他出现在我们的代码中。除非你是要写恶意占用资源的软件。
      

  8.   

    另外,注意terry6394(小猪,向前跑!) 代码的第三句比较。String p1 = "csdn";
    System.out.println(p1 == "csdn"); 大多数虚拟机的结果是true,但是这不是java的规范规定的,而是虚拟机对代码优化(将具有相同值的String常量合并为一个保存)后的结果。所以,根据虚拟机的不同,有出现false的可能性(虽然比较难碰到)。关于对象的比较,强烈建议一律使用equals()方法。(当然,象小猪这样,作实验时使用倒也无可非议。)
      

  9.   

    以前好像有人问这个问题啊,听高手们说好像是前者分配独立内存,作为类的实例--对象的身份存在,自己拥有自己的内存,而后者是个引用,类似C中的指针,代表他指像这样一块内存,其内容是“csdn”.
    这杨说不知道会不会挨骂。。只要给分,让骂声来得更猛烈些吧,不是我人溅,就是想在骂声中学习,并得分
      

  10.   

    我学JAVA的时间不是很长,看了上面人说的有点怀疑.特意查了查资料(查的是thinking in java)确定,上面仁兄说的不是很对.
       首先和大家说说"=="和"equals()".
       先说"==",它是运算符,能应能于任何对象和原始类型,比较的是两者的引用值,决定了引用是否指向同一个对象,也就是说当两个对象的类型和值相时和出的==值也是返回假的.例如:
                         String s1=String("hello");
                         String s2=String("hello");
                         当输出s1==s2时结果为false.因为引用值不同.
       再说"euqals()",它是每个类都具有的方法,当两个分离的对象的内容和类型相配的话,String,Date,File类和所有其它override equals()的包装类返回真值.
    例如:
                         String s1=String("hello");
                         String s2=String("hello");
                         方法s1.equals(s2)返回true,
       尽管指向两个不同的对象,因为在此比较的是实际的内容的值.
       但equals()的缺省行为是比较引用值,为什么这样呢?!因为绝大多数类都实现了equals()方法所以比较的是内容而不是引用值.举个例子,当自已写一个类实,再创建两个对象,用equals()方法比较时,比较的是两对象的引用值,因为你写的类中没有实现equals().再深入的可以看看相对资料,见意看Think In Java.
                                                    谢谢!
       
      

  11.   

    月下泉声的代码,作为java代码有一处错误哟。
    String s1 = new String("hello"); 才是正确的,不过不推荐这么写。equals()方法确实是依赖于实现的,否则与==无异。
    比如
    StringBuffer sb1 = new StringBuffer("hello"); 
    StringBuffer sb2 = new StringBuffer("hello"); 
    System.out.println(sb1.equals(sb2)); 
    结果就是false,因为StringBuffer没有实现自己的equals()方法,而是沿用了Object的equals()方法,也就是==。另外,值得一提的是,也是几乎所有讨论equals()方法都会说的,实现equals()的同时一定要实现hashCode()方法。并且有那么几条规则,记不清了,自己查一下资料吧。
    基本意思就是hashCode()返回值相同的几个对象必然equals()结果均true,hashCode()不同时,必须equals()返回false。并且equals()具有交换率什么之类的。总之,不小心点儿的话,实现起来还是蛮难的。不过好像这个回帖的内容有些跑题了。关于String的equals()和hashCode(),有人实验证明hashCode()方法在非半角英文数字时会有一定的问题。具体情况还是自己查了。呵呵……
      

  12.   

    上面一个帖子中的原因部分把第一种和第二种写反了。这里更正一下:坚决支持第二种写法。p = "csdn"; 
    强烈反对第一种写法。p = new String("csdn"); // <- 枪毙枪毙 x_x原因:
    第一种写法严重浪费系统资源。
    第二种写法会在内存中保存一个String类型的常量。无法被垃圾回收机制回收。
    第一种写法会在heap中动态开辟一块内存保存一个String类型的对象,可以被垃圾回收。但是在产生这个动态内存的同时,因为使用常量来定义(注意new String之后括号里面的东西),所以,与此同时同样会在内存中保存一个永不被回收的Strign类型常量。造成内存的重复浪费,同时new一个对象时的那不小的CPU开销和随后垃圾回收所用的资源也是白白浪费。综上,忘掉p = new String("csdn");这种垃圾写法吧。永远不要让他出现在我们的代码中。除非你是要写恶意占用资源的软件。
      

  13.   

    不好意思,没有写new,真不应该啊,见笑了!!!呵呵
      

  14.   

    我学JAVA的时间不是很长,看了上面人说的有点怀疑.特意查了查资料(查的是thinking in java)确定,上面仁兄说的不是很对.
       首先和大家说说"=="和"equals()".
       先说"==",它是运算符,能应能于任何对象和原始类型,比较的是两者的引用值,决定了引用是否指向同一个对象,也就是说当两个对象的类型和值相时和出的==值也是返回假的.例如:
                         String s1=new String("hello");
                         String s2=new String("hello");
                         当输出s1==s2时结果为false.因为引用值不同.
       再说"euqals()",它是每个类都具有的方法,当两个分离的对象的内容和类型相配的话,String,Date,File类和所有其它override equals()的包装类返回真值.
    例如:
                         String s1=new String("hello");
                         String s2=new String("hello");
                         方法s1.equals(s2)返回true,
       尽管指向两个不同的对象,因为在此比较的是实际的内容的值.
       但equals()的缺省行为是比较引用值,为什么这样呢?!因为绝大多数类都实现了equals()方法所以比较的是内容而不是引用值.举个例子,当自已写一个类实,再创建两个对象,用equals()方法比较时,比较的是两对象的引用值,因为你写的类中没有实现equals().再深入的可以看看相对资料,见意看Think In Java.
      

  15.   

    “java系统会自动为每一用双引号括起来的字符串常量创建一个String对象”
                         --Thinking In Java(中文版)
    也就是说“string”和new(“string”)是完全相同的,后者只是前的的一种简略的写法。作用是相同的。这一点,在中国的很多教材都有介绍,希望上面的仁兄多看看相关的资料,不要空想!
      

  16.   

    楼上的仁兄,希望多自己写程序做做实验,不要只相信所谓教材中的说法。我这里有我写的一个实际的程序可以证明,String s1 = "hello";与String s2 = new String("hello"); 是不同的。//--------------------------------------------------------------
    import java.lang.ref.WeakReference;
    /**
     * Class to research strings. 
     * constant string like "AAA" won't be reclaimed while instance created by new will. 
     * when you new a String by a constant string, there will be two memory field stored the same value. 
     * so initialize a String by constant String is recommended. 
     */public class StringResearch { public static void main(String[] args) {
    String a = "AAA"; 
    String b = new String("AAA");  WeakReference wra = new WeakReference(a); 
    WeakReference wrb = new WeakReference(b); 

    a = null; 
    b = null;  System.gc(); 

    System.out.println(wra.get()); 
    System.out.println(wrb.get()); 
    }}
    //--------------------------------------------------------君可知,马谡是怎么死的?
      

  17.   

    1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。
    2. 栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。另外,栈数据可以共享,详见第3点。堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
    3. Java中的数据类型有两种。基本类型(primitive types), 共有8种,即int, short, long, byte, float, double, boolean, char。存在于栈中。另一种是包装类数据,如Integer, String, Double等将相应的基本数据类型包装起来的类。这些类数据全部存在于堆中.String str = "abc";和String str = new String("abc");和char[] c = {'a','b','c'};String str=new String(c);都采用堆存储String str = "abc";在栈中如果没有存放值为"abc"的地址,等同于:
    String temp=new String("abc");
    String str=temp;关于String str = "abc"的内部工作。Java内部将此语句转化为以下几个步骤:
    (1)先定义一个名为str的对String类的对象引用变量:String str;
    (2)在栈中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为"abc"的地址,接着创建一个新的String类的对象o,并将o的字符串值指向这个地址,而且在栈中这个地址旁边记下这个引用的对象o。如果已经有了值为"abc"的地址,则查找对象o,并返回o的地址。
    (3)将str指向对象o的地址。使用String str = "abc";的方式,可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。char[] c = {'a','b','c'};String str=new String(c);等同于:
    String str = new String('a'+'b'+'c');
    ******************************************************************************
    转贴:http://community.csdn.net/Expert/topic/4848/4848360.xml?temp=9.325808E-02
    看完之后真正的明白了,感谢!  和大家一起分享!!
    ******************************************************************************
      

  18.   

    /**
         * Initializes a newly created <code>String</code> object so that it
         * represents the same sequence of characters as the argument; in other
         * words, the newly created string is a copy of the argument string. Unless 
         * an explicit copy of <code>original</code> is needed, use of this 
         * constructor is unnecessary since Strings are immutable. 
         *
         * @param   original   a <code>String</code>.
         */
        public String(String original) {
      this.count = original.count;
      if (original.value.length > this.count) {
          // The array representing the String is bigger than the new
          // String itself.  Perhaps this constructor is being called
          // in order to trim the baggage, so make a copy of the array.
          this.value = new char[this.count];
          System.arraycopy(original.value, original.offset,
           this.value, 0, this.count);
      } else {
          // The array representing the String is the same
          // size as the String, so no point in making a copy.
          this.value = original.value;
      }
        }
      

  19.   

    这个是java中new String(String original)的构造函数
      

  20.   

    ztroma(风里密码),你别在这装,我刚学JAVA,我怎么知道是不是"老生常谈".
    不会的就要弄清楚.别在这以老买老,我最看不起了!!