07_编译期常量与运行期常量的区别及数组创建本质分析
运行期常量
代码:
public class MyTest3 {
public static void main(String[] args) {
System.out.println(MyParent3.str);
}
}
class MyParent3{
public static final String str = UUID.randomUUID().toString();
static {
System.out.println("MyParent3 static code");
}
}
输出:
MyParent3 static code
1ed1e906-6410-4948-8cfe-1eab2111e3a4
str是个常量,但是关键在于常量的值在编译期并不能确定下来,会导致目标类被初始化;
当一个常量的值并非编译期间可以确定的,那么其值就不会被放到调用类的常量池中。这时候程序运行时,会导致主动使用这个常量所在的类,主动使用显然会导致这个类被初始化。
数组创建本质分析
代码:
public class MyTest4 {
public static void main(String[] args) {
MyParent4[] myParent4s = new MyParent4[1];
System.out.println(myParent4s.getClass());
System.out.println(myParent4s.getClass().getSuperclass());
MyParent4[][] myParent4s1 = new MyParent4[1][1];
System.out.println(myParent4s1.getClass());
System.out.println(myParent4s1.getClass().getSuperclass());
System.out.println("======1======");
int[] inta = new int[1];
System.out.println(inta.getClass());
System.out.println(inta.getClass().getSuperclass());
char[] chars = new char[1];
System.out.println(chars.getClass());
System.out.println(chars.getClass().getSuperclass());
boolean[] booleans = new boolean[1];
System.out.println(booleans.getClass());
System.out.println(booleans.getClass().getSuperclass());
short[] shorts = new short[1];
System.out.println(shorts.getClass());
System.out.println(shorts.getClass().getSuperclass());
byte[] bytes = new byte[1];
System.out.println(bytes.getClass());
System.out.println(bytes.getClass().getSuperclass());
}
}
class MyParent4{
static{
System.out.println("MyParent4 static block");
}
}
输出:
class [Ltop.tomxwd.classloader.MyParent4;
class java.lang.Object
class [[Ltop.tomxwd.classloader.MyParent4;
class java.lang.Object
======1======
class [I
class java.lang.Object
class [C
class java.lang.Object
class [Z
class java.lang.Object
class [S
class java.lang.Object
class [B
class java.lang.Object
对于数组实例来说,其类型是由JVM在运行期动态生成的表示为[Lxxx.xxx.Xxx这种形式。动态生成的类型,其父类是Object。
对于数组来说,JavaDoc经常将构成数组的元素称为Component,实际上就是将数组降低一个维度后的类型。
反编译:
Compiled from "MyTest4.java"
public class top.tomxwd.classloader.MyTest4 {
public top.tomxwd.classloader.MyTest4();
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_1
1: anewarray #2 // class top/tomxwd/classloader/MyParent4
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: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
18: aload_1
19: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
22: invokevirtual #6 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
25: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
28: iconst_1
29: iconst_1
30: multianewarray #7, 2 // class "[[Ltop/tomxwd/classloader/MyParent4;"
34: astore_2
35: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
38: aload_2
39: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
42: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
45: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
48: aload_2
49: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
52: invokevirtual #6 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
55: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
58: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
61: ldc #8 // String ======1======
63: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
66: iconst_1
67: newarray int
69: astore_3
70: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
73: aload_3
74: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
77: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
80: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
83: aload_3
84: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
87: invokevirtual #6 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
90: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
93: iconst_1
94: newarray char
96: astore 4
98: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
101: aload 4
103: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
106: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
109: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
112: aload 4
114: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
117: invokevirtual #6 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
120: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
123: iconst_1
124: newarray boolean
126: astore 5
128: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
131: aload 5
133: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
136: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
139: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
142: aload 5
144: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
147: invokevirtual #6 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
150: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
153: iconst_1
154: newarray short
156: astore 6
158: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
161: aload 6
163: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
166: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
169: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
172: aload 6
174: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
177: invokevirtual #6 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
180: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
183: iconst_1
184: newarray byte
186: astore 7
188: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
191: aload 7
193: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
196: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
199: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
202: aload 7
204: invokevirtual #4 // Method java/lang/Object.getClass:()Ljava/lang/Class;
207: invokevirtual #6 // Method java/lang/Class.getSuperclass:()Ljava/lang/Class;
210: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
213: return
}
助记符:
-
anewarray:创建一个引用类型(如类、接口、数组)的数组,并将其引用值压入栈顶;
-
newarray:表示创建一个指定的原始类型(如int、float、char等)数组,并将其引用值压入栈顶;
评论区