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

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

 
  1. public class MyTest3 {

  2. public static void main(String[] args) {

  3. System.out.println(MyParent3.str);

  4. }

  5. }

  6. class MyParent3{

  7. public static final String str =UUID.randomUUID().toString();

  8. static{

  9. System.out.println("Myparnet3 static bloack");

  10. }

  11. }

运行结果:

 
  1. Myparnet3 static bloack

  2. 04d27b8c-5480-497d-83cc-8b924e5889a5

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

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

接下来看一下数组的形式

 
  1. public class MyTest4 {

  2. public static void main(String[] args) {

  3. // MyParent4 myParent4 = new MyParent4(); 毫无疑问这个会触发初始化,属于主动调用

  4. MyParent4 [] myParent4s = new MyParent4[1];

  5. System.out.println(myParent4s.getClass());

  6. System.out.println(myParent4s.getClass().getSuperclass());

  7. MyParent4 [][] myParent4s1 = new MyParent4[1][1];

  8. System.out.println(myParent4s1.getClass());

  9. System.out.println(myParent4s1.getClass().getSuperclass());

  10. System.out.println("==============");

  11. int [] ints = new int[1];

  12. System.out.println(ints.getClass());

  13. System.out.println(ints.getClass().getSuperclass());

  14. byte [] bytes = new byte[1];

  15. System.out.println(bytes.getClass());

  16. System.out.println(bytes.getClass().getSuperclass());

  17. short [] shorts = new short[1];

  18. System.out.println(shorts.getClass());

  19. System.out.println(shorts.getClass().getSuperclass());

  20. boolean [] booleans =new boolean[1];

  21. System.out.println(booleans.getClass());

  22. System.out.println(booleans.getClass().getSuperclass());

  23. }

  24. }

  25. class MyParent4{

  26. static {

  27. System.out.println("MyParent4 static bloack");

  28. }

  29. }

运行结果:

 
  1. class [Lcom.twodragonlake.jvm.classloader.MyParent4;

  2. class java.lang.Object

  3. class [[Lcom.twodragonlake.jvm.classloader.MyParent4;

  4. class java.lang.Object

  5. ==============

  6. class [I

  7. class java.lang.Object

  8. class [B

  9. class java.lang.Object

  10. class [S

  11. class java.lang.Object

  12. class [Z

  13. class java.lang.Object

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

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

助记词:

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值