您的位置:首页 > 其它

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

2014-05-21 11:23 603 查看
这句代码到底创建了几个对象?研究了好一阵,现在才能说清楚。
package com.sun.test;

public class Test<T> {
/**
* @param args
*/
public static void main(String[] args) {
String str=new String("abc");
}
}
我们来看下这段简单代码的字节码:
<pre name="code" class="java">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<T extends java.lang.Object> extends java.lang.Object
SourceFile: "Test.java"
Signature: #35                          // <T:Ljava/lang/Object;>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               <init>
#10 = Utf8               ()V
#11 = Utf8               Code
#12 = Methodref          #3.#13         //  java/lang/Object."<init>":()V
#13 = NameAndType        #9:#10         //  "<init>":()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<TT;>;
#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."<init>":(Ljava/lang/String;)V
#27 = NameAndType        #9:#28         //  "<init>":(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               <T:Ljava/lang/Object;>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."<init>":()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<TT;>;

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."<init>":(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<T> {
/**
* @param args
*/
public static void main(String[] args) {
String str=new String("abc");
str.intern();
}
}
这样的话,在JDK 1.6和1.7没有区别都是创建一个对象。因为String pool已经有了abc。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: