zoukankan      html  css  js  c++  java
  • JVM之类加载器中篇

    先看一段代码吧!

    package com.tfdd.test;
    
    /**
     * @desc 
     * @author chenqm 
     * @date 2016年2月15日
     */
    public class FinalTest {
    
        public static void main(String[] args) {
            System.out.println(FinalTest0.a);
        }
        
    }
    class FinalTest0{
        public static final int a = 6/3;
        static{
            System.out.println("FinalTest0 static block");
        }
    }

    输出结果可知吗?

    我第一次看到的时候很肯定的认为是 

    FinalTest0 static block

    2

    然并卵~正确的结果是:

    2

    我只能说心好累,好吧?再看一段代码:

    package com.tfdd.test;
    
    import java.util.Random;
    
    /**
     * @desc 
     * @author chenqm 
     * @date 2016年2月15日
     */
    public class FinalTest {
    
        public static void main(String[] args) {
            System.out.println(FinalTest0.a);
        }
        
    }
    class FinalTest0{
        public static final int a = new Random().nextInt(100);
        static{
            System.out.println("FinalTest0 static block");
        }
    }

    结果是:

    FinalTest0 static block
    8

    这两段代码的区别就在于 a的赋值过程。 6/3 对于编译阶段是可知,所以此时的a是一个常量,而 new Random().nextInt(100)是一个编译阶段不可知的值。

    这个时候又要谈到一个上一篇中提到的概念,所有的JAVA虚拟机实现必须在每个类或接口被JAVA程序“首次主动使用”时才初始化他们。

    确实a是属于首次主动使用的一种特殊的情况,之所以特殊,是因为a是静态变量,符合主动使用的情况,但是6/3的结果是编译可知的,并且a是final的,只能被初始化一次,换句话说a的值是编译可知的,这样即使是首次主动使用,也不会对类进行初始化,因为不需要初始化,程序就能得到a的正确的值,果然,连虚拟机都是爱偷懒的!

  • 相关阅读:
    条件判断和循环
    list 和tuple的使用
    python的五大数据类型
    简单的一个程序,猜字游戏
    redhat7 nfs的配置以及auto自动挂载
    nmcli添加网卡 并且修改设备名字 添加IP地址
    RHEL7 系统ISCSI存储环境搭建
    Java分布式锁
    24个Jvm面试题总结及答案
    最新天猫3轮面试题目:虚拟机+并发锁+Sql防注入+Zookeeper
  • 原文地址:https://www.cnblogs.com/think-in-java/p/5190758.html
Copyright © 2011-2022 走看看