我在跟着[张龙老师]学习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

intclass [I
byteclass [B
shortclass [S
doubleclass [D
floatclass [F
booleanclass [Z
charclass [C
longclass [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,晚上在看看其他技能点,充实的一天。

 

posted @ 2019-11-16 12:18  不朽_张  阅读(295)  评论(0)    收藏  举报