我在跟着[张龙老师]学习JVM 之 数组创建本质分析
数组与对象的关系?
谈 数组创建本质之前需要先了解 一下 数组和对象的关系是什么?我们结合案例来看,
创建类的实例
案例一(代码):创建一个 TestA 对象,TestA 中的静态块是否被执行?
public class Test1 { public static void main(String[] args) { TestA testA =new TestA(); } } class TestA { static { System.out.println("my name is TestA"); } }
案例一(结果):创建一个类的实例会对该类进行初始化,会被主动使用,所以执行了 静态块中的代码。
my name is TestA
Process finished with exit code 0
创建数组
案例二(代码):将 TestA 定义成数组,看 TestA 是否被初始化?
public class Test1 { public static void main(String[] args) { TestA[] testA =new TestA[1]; } } class TestA { static { System.out.println("my name is TestA"); } }
案例二(结果):其实什么都没有(Process finished with exit code 0 只是idea 自动打印的)。定义成 TestA数组 并没有导致 TestA 被初始化。
Process finished with exit code 0
集合
案例三(代码):出于好奇我又改为了集合
public class Test1 { public static void main(String[] args) { List<TestA> testA =new ArrayList<>(); } } class TestA { static { System.out.println("my name is TestA"); } }
案例三(结果):和数组一样,也不会对 该类进行初始化。
Process finished with exit code 0
数组的类型
案例四(代码):数组是属于什么类型?
public class Test1 { public static void main(String[] args) { TestA[] test=new TestA[1]; System.out.println(test.getClass()); } } class TestA { static { System.out.println("my name is TestA"); } }
案例四(结果):注意结果中红色部分,这表示声明出来的数组从属于 什么类型。集合的话,则是实际创建的那个类型 如:class java.util.ArrayList。这里提到集合只是想做个对比,集合本身就是一个类,所以创建的是实例,就是他本身类的实例,并从属某个泛型的类型。
class [Lcom.test.TestA;
分析
数组类型是一个特殊的类型,表示为 class [Lcom.xxx.xx(若二维数组则是 class[[Lcom.xxx.xx),是JVM在运行期 创建出来的(类似于动态代理)。这个形式动态生成的类型,其父类的类型直接就是Object。
TestA[] test=new TestA[1]; System.out.println(test.getClass().getSuperclass());
#运行结果 class java.lang.Object
对于数组来说,JavaDoc经常将构成数组的元素为Component(组件),实际上就是将数组降低一个维度后的类型。
基本类型数组
上面讲的都是引用类型的数组会是什么样的,java 有八大基本类型,就一一列一下,他们类型是什么样的(我也很好奇)。
案例五(代码):
public static void main(String[] args) { int[] i=new int[1]; System.out.println("int:"+i.getClass()); byte[] b=new byte[1]; System.out.println("byte:"+b.getClass()); short[] s=new short[1]; System.out.println("short:"+s.getClass()); double[] d=new double[1]; System.out.println("double:"+d.getClass()); float[] f=new float[1]; System.out.println("float:"+f.getClass()); boolean[] bool=new boolean[1]; System.out.println("boolean:"+bool.getClass()); char[] c=new char[1]; System.out.println("char:"+c.getClass()); long[] l=new long[1]; System.out.println("long:"+l.getClass()); }
案例五(结果):意外的的是,引用类型的 是以 [L 开头的,基本类型 long 则是用 [J。
int:class [I byte:class [B short:class [S double:class [D float:class [F boolean:class [Z char:class [C long:class [J Process finished with exit code 0
案例五(反编译):
$ javap -c Test1.class Compiled from "Test1.java" public class com.test.Test1 { public com.test.Test1(); 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: newarray int 3: astore_1 4: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 7: new #3 // class java/lang/StringBuilder 10: dup 11: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 14: ldc #5 // String int: 16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 19: aload_1 20: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class; 23: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 26: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 29: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 32: iconst_1 33: newarray byte 35: astore_2 36: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 39: new #3 // class java/lang/StringBuilder 42: dup 43: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 46: ldc #11 // String byte: 48: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 51: aload_2 52: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class; 55: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 58: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 61: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 64: iconst_1 65: newarray short 67: astore_3 68: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 71: new #3 // class java/lang/StringBuilder 74: dup 75: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 78: ldc #12 // String short: 80: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 83: aload_3 84: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class; 87: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 90: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 93: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 96: iconst_1 97: newarray double 99: astore 4 101: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 104: new #3 // class java/lang/StringBuilder 107: dup 108: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 111: ldc #13 // String double: 113: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 116: aload 4 118: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class; 121: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 124: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 127: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 130: iconst_1 131: newarray float 133: astore 5 135: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 138: new #3 // class java/lang/StringBuilder 141: dup 142: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 145: ldc #14 // String float: 147: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 150: aload 5 152: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class; 155: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 158: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 161: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 164: iconst_1 165: newarray boolean 167: astore 6 169: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 172: new #3 // class java/lang/StringBuilder 175: dup 176: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 179: ldc #15 // String boolean: 181: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 184: aload 6 186: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class; 189: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 192: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 195: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 198: iconst_1 199: newarray char 201: astore 7 203: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 206: new #3 // class java/lang/StringBuilder 209: dup 210: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 213: ldc #16 // String char: 215: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 218: aload 7 220: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class; 223: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 226: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 229: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 232: iconst_1 233: newarray long 235: astore 8 237: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 240: new #3 // class java/lang/StringBuilder 243: dup 244: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V 247: ldc #17 // String long: 249: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 252: aload 8 254: invokevirtual #7 // Method java/lang/Object.getClass:()Ljava/lang/Class; 257: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 260: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 263: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 266: return }
注记符
- newarray 表示为创建一个基本类型的数组,并将其引用值加入且推送至栈顶。
- anewarray 表示为创建一个引用类型的(类,接口,数组)并其引用类型的值加入且推送至栈顶。
笔后语录
今天是周六,现在已经是中午十二点了,花了一上午时间,才一个40分钟的教学视频,看了不仅仅只是看了,好需要思考。但是有时候在想,这时间是否花得值?这是个深奥的问题。下午在看看书,学习学习python,晚上在看看其他技能点,充实的一天。

浙公网安备 33010602011771号