这句代码到底创建了几个对象?研究了好一阵,现在才能说清楚。
package com.sun.test;
public class Test<T> {
T a;
/**
* @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;
{
T a;
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> {
T a;
/**
* @param args
*/
public static void main(String[] args) {
String str=new String("abc");
str.intern();
}
}
这样的话,在JDK 1.6和1.7没有区别都是创建一个对象。因为String pool已经有了abc。
String str=new String("abc")到底创建了几个对象,布布扣,bubuko.com
String str=new String("abc")到底创建了几个对象
原文:http://blog.csdn.net/aigoogle/article/details/26453811