这句代码到底创建了几个对象?研究了好一阵,现在才能说清楚。
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