JVM 原理三:编译期常量与运行期常量的区别及数组创建本质分析

>>号外:关注“Java精选”公众号,回复“2021面试题”关键词,领取全套500多份Java面试题文件。

上一个例子我们用的final是一个字面量“hello world”,这次我们改一下使用UUID为常量赋值,注意:UUID是多少只有在运行期间才会被确定。

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("Myparnet3 static bloack");
    }
}

运行结果:

Myparnet3 static bloack
04d27b8c-5480-497d-83cc-8b924e5889a5

当一个常量的值并非编译期可以确定的,那么其值就不会被放到调用类的常量池中,

这时的程序运行时,会导致主动使用这个常量所在的类,显然会导致这个类被初始化。

接下来看一下数组的形式

public class MyTest4 {
    public static void main(String[] args) {
       // MyParent4 myParent4 = new MyParent4(); 毫无疑问这个会触发初始化,属于主动调用
        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("==============");
        int [] ints = new int[1];
        System.out.println(ints.getClass());
        System.out.println(ints.getClass().getSuperclass());

        byte [] bytes = new byte[1];
        System.out.println(bytes.getClass());
        System.out.println(bytes.getClass().getSuperclass());

        short [] shorts = new short[1];
        System.out.println(shorts.getClass());
        System.out.println(shorts.getClass().getSuperclass());

        boolean [] booleans =new boolean[1];
        System.out.println(booleans.getClass());
        System.out.println(booleans.getClass().getSuperclass());


    }
}

class MyParent4{
    static {
        System.out.println("MyParent4 static bloack");
    }
}

运行结果:

class [Lcom.twodragonlake.jvm.classloader.MyParent4;
class java.lang.Object
class [[Lcom.twodragonlake.jvm.classloader.MyParent4;
class java.lang.Object
==============
class [I
class java.lang.Object
class [B
class java.lang.Object
class [S
class java.lang.Object
class [Z
class java.lang.Object

对于数组实例来说,其类型是由JVM在运行期间动态生成的,表示为[Lcom.twodragonlake.jvm.classloader.MyParent4这种形式。动态生成的类型(类似于动态代理),其父类型就是Object

对于数组来说,JavaDoc经常讲构成数组的元素称为Component,实际上就是将数组降低一个维度后的类型。

助记词:

anewarray : 表示创建一个引用类型的(如类、接口、数组)数组,并将其引用值压入栈顶

newarray : 表示创建一个指定的原始类型(如int、float、char等)的数组,并将其压入栈顶

作者:魔鬼_

blog.csdn.net/wzq6578702/article/details/79370662

往期精选  点击标题可跳转

JVM 原理二:常量的本质含义与反编译及助记符详解

JVM原理一:类加载器深入解析与阶段分解

Java 中统计代码执行耗时,列举 4 种优雅的解决方案

MySQL 分页使用 limit 和 offset 参数为什么会导致执行变慢?

全网可能是最全的 JAVA 日志框架适配、冲突解决方案

数据库在哪些场景下导致索引失效,索引何时会失效?

为什么 Redis 越来越慢了?延迟问题定位排查与分析

Spring 框架中导致 @Transactional 事务注解 3 种失效场景分析及解决方法

放弃 JDK8 中 StringBuilder,使用 StringJoiner 辅助类,真香!

面试时这样回答 Java 应用性能调优,回报是更多 Money!

面试官问:你说一说 HashMap 是如何解决 hash 冲突的?

点个赞,就知道你“在看”!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值