目 录CONTENT

文章目录

07_编译期常量与运行期常量的区别及数组创建本质分析

ByteNews
2019-08-15 / 0 评论 / 0 点赞 / 16,671 阅读 / 6,416 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-01-16,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

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等)数组,并将其引用值压入栈顶;

0

评论区