String str=new String("abc")到底创建了几个对象

这句代码到底创建了几个对象?研究了好一阵,现在才能说清楚。
package com.sun.test;


public class Test {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String str=new String("abc");
	}
}
我们来看下这段简单代码的字节码:
Classfile /D:/Workspaces/MyEclipse10/JavaTools/bin/com/sun/test/Test.class
  Last modified 2014-5-21; size 677 bytes
  MD5 checksum 65b161d88c06818975226b4792c9fe1b
  Compiled from "Test.java"
public class com.sun.test.Test extends java.lang.Object
  SourceFile: "Test.java"
  Signature: #35                          // Ljava/lang/Object;
  minor version: 0
  major version: 50
  flags: ACC_PUBLIC, ACC_SUPER

Constant pool:
   #1 = Class              #2             //  com/sun/test/Test
   #2 = Utf8               com/sun/test/Test
   #3 = Class              #4             //  java/lang/Object
   #4 = Utf8               java/lang/Object
   #5 = Utf8               a
   #6 = Utf8               Ljava/lang/Object;
   #7 = Utf8               Signature
   #8 = Utf8               TT;
   #9 = Utf8               
  #10 = Utf8               ()V
  #11 = Utf8               Code
  #12 = Methodref          #3.#13         //  java/lang/Object."":()V
  #13 = NameAndType        #9:#10         //  "":()V
  #14 = Utf8               LineNumberTable
  #15 = Utf8               LocalVariableTable
  #16 = Utf8               this
  #17 = Utf8               Lcom/sun/test/Test;
  #18 = Utf8               LocalVariableTypeTable
  #19 = Utf8               Lcom/sun/test/Test;
  #20 = Utf8               main
  #21 = Utf8               ([Ljava/lang/String;)V
  #22 = Class              #23            //  java/lang/String
  #23 = Utf8               java/lang/String
  #24 = String             #25            //  abc
  #25 = Utf8               abc
  #26 = Methodref          #22.#27        //  java/lang/String."":(Ljava/lang/String;)V
  #27 = NameAndType        #9:#28         //  "":(Ljava/lang/String;)V
  #28 = Utf8               (Ljava/lang/String;)V
  #29 = Utf8               args
  #30 = Utf8               [Ljava/lang/String;
  #31 = Utf8               str
  #32 = Utf8               Ljava/lang/String;
  #33 = Utf8               SourceFile
  #34 = Utf8               Test.java
  #35 = Utf8               Ljava/lang/Object;
{
    flags: 

    Signature: #8                           // TT;

  public com.sun.test.Test();
    flags: ACC_PUBLIC

    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #12                 // Method java/lang/Object."":()V
         4: return        
      LineNumberTable:
        line 4: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   Lcom/sun/test/Test;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/sun/test/Test;

  public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC

    Code:
      stack=3, locals=2, args_size=1
         0: new           #22                 // class java/lang/String
         3: dup           
         4: ldc           #24                 // String abc
         6: invokespecial #26                 // Method java/lang/String."":(Ljava/lang/String;)V
         9: astore_1      
        10: return        
      LineNumberTable:
        line 10: 0
        line 11: 10
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0      11     0  args   [Ljava/lang/String;
              10       1     1   str   Ljava/lang/String;
}


 
  
类文件中包括了abc这个字面量,当这个类运行的时候,类加载器首先会加载本类,类文件中的constant pool(比如那个abc)会被加载进运行时常量池,并以String对象保存在运行时常量池中。然后运行main方法,这个时候String pool中已经包含了abc的Sting 对象,所以这个时候只有创建了一个对象,也就是new String(),在堆中的那个对象。然后在讨论String中的intetrn方法:

Open Declaration String java.lang.String.intern()


Returns a canonical representation for the string object. 

A pool of strings, initially empty, is maintained privately by the class String. 

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. 

It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true. 

All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

Returns:
a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.


也就是说如果 String pool中包含了内容相同的字符串,便会把这个对象的引用赋到需要这个对象的创建方法中。
package com.sun.test;


public class Test {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String str=new String("abc");
		str.intern();
	}
}
这样的话,在JDK 1.6和1.7没有区别都是创建一个对象。因为String pool已经有了abc。



你可能感兴趣的:(java基础-String)