有关Java虚拟机类加载机制相关的文章一搜一大把,笔者这儿也不必再赘述一遍了。笔者这儿捞出一道code题要各位大佬来把玩把玩,假定你一眼就看出了端倪,那么祝贺你,你可以下山了:

  public class StaticTest
  {
     public static void main(String[] args)
     {
         staticFunction();
     }

     static StaticTest st = new StaticTest();

     static
     {
         System.out.println("1");
     }

     {
         System.out.println("2");
     }

     StaticTest()
     {
         System.out.println("3");
         System.out.println("a="+a+",b="+b);
     }

     public static void staticFunction(){
         System.out.println("4");
     }

     int a=110;
     static int b =112;
  }
  问题:请问这段程序的输出是什么?一般关于这类问题,小伙伴们脑海中必定浮现出这样的常识点:

  Java中赋值次第:

  父类的静态变量赋值

  自身的静态变量赋值

  父类成员变量赋值和父类块赋值

  父类结构函数赋值

  自身成员变量赋值和自身块赋值

  自身结构函数赋值

  按照这个理论输出是什么呢?答案输出:1 4,这样正确嚒?必定不正确啦,(midea808)这儿不是说上面的规矩不正确,而是说不能简略的套用这个规矩。 正确的答案是:

  2
  3
  a=110,b=0
  1
  4
  有没有答对呢?这儿首要的点之一:实例初始化不一定要在类初始化结束之后才开端初始化。 类的生命周期是:加载->验证->准备->解析->初始化->运用->卸载,只要在准备阶段和初始化阶段才会触及类变量的初始化和赋值,因此只针对这两个阶段进行剖析;

  类的准备阶段需求做是为类变量分配内存并设置默认值,因此类变量st为null、b为0;(需求留心的是假定类变量是final,编译时javac将会为value生成ConstantValue特征,在准备阶段虚拟机就会根据ConstantValue的设置将变量设置为指定的值,假定这儿这么定义:static final int b=112,那么在准备阶段b的值就是112,而不再是0了。)

  类的初始化阶段需求做的是施行类结构器(类结构器是编译器搜集悉数静态语句块和类变量的赋值语句按语句在源码中的次第吞并生成类结构器,政策的结构方法是(),类的结构方法是(),可以在仓库信息中看到),因此先施行第一条静态变量的赋值语句即st = new StaticTest (),此刻会进行政策的初始化,政策的初始化是先初始化成员变量再施行结构方法,因此打印2->设置a为110->施行结构方法(打印3,此刻a现已赋值为110,但是b仅仅设置了默认值0,并未结束赋值动作),等政策的初始化结束后持续施行之前的类结构器的语句,接下来就不具体说了,按照语句在源码中的次第施行即可。

  这儿面还牵涉到一个冷常识,就是在嵌套初始化时有一个特别的逻辑。特别是内嵌的这个变量恰好是个静态成员,(grandwaycanada)并且是本类的实例。 这会导致一个诙谐的现象:“实例初始化居然出现在静态初始化之前”。 其实并没有提早,你要知道java记载初始化与否的时机。看一个简化的代码,把关键问题说明清楚:

  public class Test {
     public static void main(String[] args) {
         func();
     }
     static Test st = new Test();
     static void func(){}
  }
  根据上面的代码,有以下进程:

  首先在施行此段代码时,首先由main方法的调用触发静态初始化。

  在初始化Test 类的静态部分时,遇到st这个成员。

  但恰巧这个变量引证的是本类的实例。

  那么问题来了,此刻静态初始化进程还没结束就要初始化实例部分了。是这样么?

  从人的角度是的。但从java的角度,一旦开端初始化静态部分,不论是否结束,后续都不会再从头触发静态初始化流程了。

  因此在实例化st变量时,实际上是把实例初始化嵌入到了静态初始化流程中,并且在楼主的问题中,嵌入到了静态初始化的开端方位。这就导致了实例初始化完全至于静态初始化之前。这也是导致a有值b没值的原因。

  毕竟再考虑到文本次第,效果就清楚明了了。

  具体看到这儿,心中大概有个结论了吧。

很多人都会做错的一道JVM题?【分享】的更多相关文章

  1. 大部分人都会做错的经典JS闭包面试题

    由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...

  2. 关于ftp的学习:ftp很多人都会用。但会用,不代表我们真正了解它。

    ftp.sftp.ftps,您是否是也跟我一样搞不清楚他们的真正意义.它们之间有关联吗(究竟是何种关联),有区别吗(区别倒地在哪里). 亦或是以为自己知道它们,可我们真的了解并认识它们了吗? 如果您被 ...

  3. 这道js面试题号称99%的人会做错

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. 一道简单的 Java 笔试题,但值得很多人反思!

    前言 面试别人,对我来说是一件新奇事,以前都是别人面试我.我清楚地知道,我在的地域与公司,难以吸引到中国的一流软件人才.所以,我特地调低了期望,很少问什么深入的技术问题,只问一些广泛的.基础的.我只要 ...

  5. 这道面试必问的JVM面试题70%的Java程序员会做错

    前言 聊聊JVM,一个熟悉又陌生的名词,从认识Java的第一天起,我们就会听到这个名字,在参加工作的前一两年,面试的时候还会经常被问到JDK,JRE,JVM这三者的区别. JVM可以说和我们是老朋友了 ...

  6. 神贴真开眼界:为什么很多人倡导重视能力和素质,但同时对学历有严格要求?——代表了上一场比赛的输赢,招聘成本很重要。如果上一场游戏失败了,尽量让自己成为当前群体的尖子。学历只是其中的一个作品而已,但学历代表了学生时代为之做出的牺牲。人群自有偏向集中性 good

    对于软件工程师职位,没学历没关系,如果真觉得自己才高八斗,请在简历里附上 github项目链接或者 appstore/google play上你的作品.如果学历比别人低,那么想必是把时间和精力用在了其 ...

  7. 为什么很多人坚信“富贵险中求”?

    之家哥 2017-11-15 09:12:31 微信QQ微博 下载APP 摘要 网贷之家小编根据舆情频道的相关数据,精心整理的关于<为什么很多人坚信"富贵险中求"?>的 ...

  8. 我来科普一下为毛很多人升级了20M的电信光纤宽带反而感觉速度更卡了

    下载(在线看视频,看网页,下载游戏这类都是属于下载类应用) 为毛很多人升级20M光纤更慢了呢? 因为电信对你的上传速度做了手脚, 8M以及以上家用光纤宽带全部上传限速到100KB/s  也就是1M带宽 ...

  9. (转)Groupon前传:从10个月的失败作品修改,1个月找到成功 并不挶泥在这个点子上面,它反而往后站一步,看看他们已经做好的这个网站,可以再怎么包装成另一个完完全全不同的网站?所有的人所做的每件失败的事情中, 一定有碰到或含有成功的答案」在里面,只是他们不知道而已。 人不怕失败」,只怕宣布失败」

    (转)Groupon前传:从10个月的失败作品修改,1个月找到成功 今天读到 一个非常励志人心的故事 ,就像现在「叶问」有「前传」,最近很火红的团集购网站Groupon 也出现了「Groupon前传」 ...

随机推荐

  1. LeetCode 5273. 搜索推荐系统 Search Suggestions System

    地址 https://leetcode-cn.com/problems/search-suggestions-system/ 题目描述给你一个产品数组 products 和一个字符串 searchWo ...

  2. nodejs+Express中使用mustache模板引擎

    由于公司一个seo项目,需要我协助.此项目他人已经开发大半,由于seo需要,使用了服务器端模板引擎.我项目的后端同事说项目是go语音写的,跑项目麻烦,只给了我template和css等静态文件. 为了 ...

  3. Collection接口综述

    Collection接口 Collection是集合类基本的接口,它不提供具体的实现,集合类都继承自Collection接口,Collection代表的是一种规则,它包含的元素必须符合某种规则,比如有 ...

  4. 基础知识 Asp.Net MVC EF各版本区别

    原文:https://www.cnblogs.com/liangxiaofeng/p/5840754.html 2009年發行ASP.NET MVC 1.0版 2010年發行ASP.NET MVC 2 ...

  5. 【CodeChef】December Challenge 2019 Div1 解题报告

    点此进入比赛 这次比赛本来想好好打的,但不幸的是,这周先是要认真复习准备月考,考完又是发烧在床上躺了一个周末,所以最终没能打完. 我还是好弱啊. \(T1\):Binary XOR(点此看题面) 大致 ...

  6. python做中学(五)多线程的用法

    多线程类似于同时执行多个不同程序,多线程运行有如下优点: 使用线程可以把占据长时间的程序中的任务放到后台去处理. 用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条 ...

  7. Find 查找命令时过滤掉某些文件或目录 以及 -maxdepth、-mindepth的用法

    1)find过滤目录使用find命令在linux系统中查找文件时,有时需要忽略某些目录,可以使用"-path 过滤的目录路径 -prune -o"参数来进行过滤.不过必须注意:要忽 ...

  8. javascript 模块化 (切记:学习思想)

    模块化(切记:学习思想) 如果不用模块化编写代码,那么会具有以下问题: 代码杂乱无章,没有条理性,不便于维护,不便于复用 很多代码重复.逻辑重复 全局变量污染 不方便保护私有数据(闭包) 模块化的基本 ...

  9. css文本省略号

    这里记录下如何用CSS实现单行.多行文本溢出容器的时候用省略号代替溢出部分. 单行文本溢出容器时显示省略号的CSS实现方法 /* 规定当内容溢出元素框(容器)时隐藏 */ overflow: hidd ...

  10. win10 关闭 “在时间线中查看更多日期” 提示

    在组策略中,禁用允许上传用户活动