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的正确的值,果然,连虚拟机都是爱偷懒的!

  • 相关阅读:
    关于【最小生成树】
    题目1096:日期差值 (2009年上海交通大学计算机研究生机试真题)
    题目1432:叠筐 题目1126:打印极值点下标
    利用栈解决一些基本问题
    Redis与Python交互
    MongoDB与python 交互
    MongoDB安装
    mongodb基本操作
    MySQL与Python交互
    C++11 bind和function用法
  • 原文地址:https://www.cnblogs.com/think-in-java/p/5190758.html
Copyright © 2011-2022 走看看