续上一篇
当一个常量的值并非编译期间内可以确定的,那么其值就不会放到调用类的常量池中。这时候程序运行时,会导致主动使用这个常量所在类,即让该类初始化。
先上代码块
import java.util.UUID;
public class Test3 {
public static void main(String[] args){
System.out.println(Parent3.str);
}
}
class Parent3{
public static final String str = UUID.randomUUID().toString();
static {
System.out.println("parent3 static block");
}
}
实例化Parent4
public class Test4 {
public static void main(String[] args){
Parent4 parent4 = new Parent4();
System.out.println(parent4.getClass());
}
}
class Parent4{
static {
System.out.println("parent4 static block");
}
}
运行结果:
parent4 static block
class Parent4
class Parent4 说明该类型是一个Parent4类型,静态方法也被打印出来了,class被主动使用。再看看下面代码。
public class Test4 {
public static void main(String[] args){
Parent4[] parents = new Parent4[3];
System.out.println(parents.getClass());
}
}
class Parent4{
static {
System.out.println("parent4 static block");
}
}
运行结果:
class [LParent4;
以上代码并没有打印静态方法,因为该类型是一个数组,在JVM在运行期间,类似动态代理创建的,标记:[L,并没有创建Parent4实例,附上编译文件内容。
public class Test4 {
public Test4();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: anewarray #2 // class Parent4
4: astore_1
5: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
8: aload_1
9: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
12: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
15: return
}
再试试创建二维数据,并查看输出。
public class Test4 {
public static void main(String[] args){
Parent4[][] parents = new Parent4[2][2];
System.out.println(parents.getClass());
}
}
class Parent4{
static {
System.out.println("parent4 static block");
}
}
运行结果:
class [[LParent4;
类型是一个二维数组,标记:[[L
public class Test4 {
public Test4();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_3
1: anewarray #2 // class Parent4
4: astore_1
5: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
8: aload_1
9: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
12: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
15: return
}
D:\workspace-for-yun\untitled\out\production\TestJVM>javap -c Test4.class
Compiled from "Test4.java"
public class Test4 {
public Test4();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_2
1: iconst_2
2: multianewarray #2, 2 // class "[[LParent4;"
6: astore_1
7: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
10: aload_1
11: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
14: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
17: return
}
查看三种实例的类型及其父类型。
public class Test4 {
public static void main(String[] args){
System.out.println("*****引用类型*****");
Parent4 parent4 = new Parent4();
Parent4[] parents = new Parent4[2];
Parent4[][] parent2s = new Parent4[2][2];
System.out.println("parent4类型:"+parent4.getClass());
System.out.println("parent4父类型:"+parent4.getClass().getSuperclass());
System.out.println("parents类型:"+parents.getClass());
System.out.println("parents父类型:"+parent4.getClass().getSuperclass());
System.out.println("parent2s类型:"+parent2s.getClass());
System.out.println("parent2s父类型:"+parent4.getClass().getSuperclass());
System.out.println("*****基本类型*****");
int[] list = new int[1];
System.out.println("list类型:"+list.getClass());
System.out.println("list父类型:"+list.getClass().getSuperclass());
}
}
class Parent4{
static {
System.out.println("parent4 static block");
}
}
运行结果:
*****引用类型*****
parent4 static block
parent4类型:class Parent4
parent4父类型:class java.lang.Object
parents类型:class [LParent4;
parents父类型:class java.lang.Object
parent2s类型:class [[LParent4;
parent2s父类型:class java.lang.Object
*****基本类型*****
list类型:class [I
list父类型:class java.lang.Object
总结:1.对于数组实例来说,其类型是由JVM在运行时期间动态生成的,表示为[[L....,这种形式的。动态生成的类型,其父类就是Object。
对于数组来说,JavaDoc经常将构成数组的元素为Component,实际上就是将数组降低一个维度后的类型。
反编译以上的class文件进行查看。
public class Test4 {
public Test4();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String *****引用类型*****
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: new #5 // class Parent4
11: dup
12: invokespecial #6 // Method Parent4."<init>":()V
15: astore_1
16: iconst_2
17: anewarray #5 // class Parent4
20: astore_2
21: iconst_2
22: iconst_2
23: multianewarray #7, 2 // class "[[LParent4;"
27: astore_3
28: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
31: new #8 // class java/lang/StringBuilder
34: dup
35: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
38: ldc #10 // String parent4类型:
40: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
43: aload_1
44: invokevirtual #12 // Method java/lang/Object.getClass:()Ljava/lang/Class;
47: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
50: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
53: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
56: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
59: new #8 // class java/lang/StringBuilder
62: dup
63: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
66: ldc #15 // String parent4父类型:
68: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
71: aload_1
72: invokevirtual #12 // Method java/lang/Object.getClass:()Ljava/lang/Class;
75: invokevirtual #16 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
78: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
81: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
84: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
87: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
90: new #8 // class java/lang/StringBuilder
93: dup
94: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
97: ldc #17 // String parents类型:
99: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
102: aload_2
103: invokevirtual #12 // Method java/lang/Object.getClass:()Ljava/lang/Class;
106: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
109: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
112: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
115: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
118: new #8 // class java/lang/StringBuilder
121: dup
122: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
125: ldc #18 // String parents父类型:
127: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
130: aload_1
131: invokevirtual #12 // Method java/lang/Object.getClass:()Ljava/lang/Class;
134: invokevirtual #16 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
137: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
140: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
143: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
146: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
149: new #8 // class java/lang/StringBuilder
152: dup
153: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
156: ldc #19 // String parent2s类型:
158: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
161: aload_3
162: invokevirtual #12 // Method java/lang/Object.getClass:()Ljava/lang/Class;
165: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
168: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
171: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
174: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
177: new #8 // class java/lang/StringBuilder
180: dup
181: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
184: ldc #20 // String parent2s父类型:
186: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
189: aload_1
190: invokevirtual #12 // Method java/lang/Object.getClass:()Ljava/lang/Class;
193: invokevirtual #16 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
196: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
199: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
202: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
205: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
208: ldc #21 // String *****基本类型*****
210: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
213: iconst_1
214: newarray int
216: astore 4
218: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
221: new #8 // class java/lang/StringBuilder
224: dup
225: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
228: ldc #22 // String list类型:
230: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
233: aload 4
235: invokevirtual #12 // Method java/lang/Object.getClass:()Ljava/lang/Class;
238: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
241: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
244: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
247: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
250: new #8 // class java/lang/StringBuilder
253: dup
254: invokespecial #9 // Method java/lang/StringBuilder."<init>":()V
257: ldc #23 // String list父类型:
259: invokevirtual #11 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
262: aload 4
264: invokevirtual #12 // Method java/lang/Object.getClass:()Ljava/lang/Class;
267: invokevirtual #16 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
270: invokevirtual #13 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder;
273: invokevirtual #14 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
276: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
279: return
}
助记符:
anewarray:表示创建一个引用类型的(如:类、接口、数组)数组,并将其引用值压入栈顶。
multianewarray:表示创建一个引用类型的(如:类、接口、数组)二维数组,并将其引用值压入栈顶。
newarray:表示创建一个指定的原始类型(如int、float、char等)的数组,并将其引用值压入栈顶。
注:二维数据int[][]属于一个引用类型。