很多人都会做错的一道JVM题?【分享】
有关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题?【分享】的更多相关文章
- 大部分人都会做错的经典JS闭包面试题
由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...
- 关于ftp的学习:ftp很多人都会用。但会用,不代表我们真正了解它。
ftp.sftp.ftps,您是否是也跟我一样搞不清楚他们的真正意义.它们之间有关联吗(究竟是何种关联),有区别吗(区别倒地在哪里). 亦或是以为自己知道它们,可我们真的了解并认识它们了吗? 如果您被 ...
- 这道js面试题号称99%的人会做错
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 一道简单的 Java 笔试题,但值得很多人反思!
前言 面试别人,对我来说是一件新奇事,以前都是别人面试我.我清楚地知道,我在的地域与公司,难以吸引到中国的一流软件人才.所以,我特地调低了期望,很少问什么深入的技术问题,只问一些广泛的.基础的.我只要 ...
- 这道面试必问的JVM面试题70%的Java程序员会做错
前言 聊聊JVM,一个熟悉又陌生的名词,从认识Java的第一天起,我们就会听到这个名字,在参加工作的前一两年,面试的时候还会经常被问到JDK,JRE,JVM这三者的区别. JVM可以说和我们是老朋友了 ...
- 神贴真开眼界:为什么很多人倡导重视能力和素质,但同时对学历有严格要求?——代表了上一场比赛的输赢,招聘成本很重要。如果上一场游戏失败了,尽量让自己成为当前群体的尖子。学历只是其中的一个作品而已,但学历代表了学生时代为之做出的牺牲。人群自有偏向集中性 good
对于软件工程师职位,没学历没关系,如果真觉得自己才高八斗,请在简历里附上 github项目链接或者 appstore/google play上你的作品.如果学历比别人低,那么想必是把时间和精力用在了其 ...
- 为什么很多人坚信“富贵险中求”?
之家哥 2017-11-15 09:12:31 微信QQ微博 下载APP 摘要 网贷之家小编根据舆情频道的相关数据,精心整理的关于<为什么很多人坚信"富贵险中求"?>的 ...
- 我来科普一下为毛很多人升级了20M的电信光纤宽带反而感觉速度更卡了
下载(在线看视频,看网页,下载游戏这类都是属于下载类应用) 为毛很多人升级20M光纤更慢了呢? 因为电信对你的上传速度做了手脚, 8M以及以上家用光纤宽带全部上传限速到100KB/s 也就是1M带宽 ...
- (转)Groupon前传:从10个月的失败作品修改,1个月找到成功 并不挶泥在这个点子上面,它反而往后站一步,看看他们已经做好的这个网站,可以再怎么包装成另一个完完全全不同的网站?所有的人所做的每件失败的事情中, 一定有碰到或含有成功的答案」在里面,只是他们不知道而已。 人不怕失败」,只怕宣布失败」
(转)Groupon前传:从10个月的失败作品修改,1个月找到成功 今天读到 一个非常励志人心的故事 ,就像现在「叶问」有「前传」,最近很火红的团集购网站Groupon 也出现了「Groupon前传」 ...
随机推荐
- WPF combobox数据绑定和数据获取
本文章仅为个人学习,如有错误之处请指正. 搭建WPF界面的时候,想用combobox构建一个下拉菜单,搜索的时候看到大多数都是大段代码,逻辑顺序不是很详细,摸索了大概,记录一下方便来者. 拖入comb ...
- c++用控制符控制输出格式
#include<iostream> #include<cstdio> #include<iomanip> using namespace std; int mai ...
- Linux-Bash终端快捷键
^C 终正在运行的进程或放弃当前编辑的命令^U 将光标所在字符到行首之间的所有字符删除,可以使用^E到行尾再^U来删除整行内容^Z 将前台运行的进程放入背景并暂停^D 发送EOF,结束当前输入流,如果 ...
- Linux常见命令之权限管理命令
chmod命令 chmod命令用来变更文件或目录的权限.在UNIX系统家族里,文件或目录权限的控制分别以读取.写入.执行3种一般权限来区分,另有3种特殊权限可供运用.用户可以使用chmod指令去变更文 ...
- Sql 代码规范说明
对于程序工作者来说,代码的阅读必不可少,好的代码让人读起来一目了然.神清气爽,做代码调试也可以很开的捋顺逻辑定位问题,但是如果遇到一些可读性较差,毫无规矩可言的代码,那真的比吃了翔都难受啊,如果再让你 ...
- C++ delete 和 delete []的区别
转载自https://blog.csdn.net/cbNotes/article/details/38900799 1.我们通常从教科书上看到这样的说明:delete 释放new分配的单个对象指针指向 ...
- go-运算符
算术运算符 ++,--只能放在变量后面,不能放在前面 独立使用 目的:更简洁 go语言不支持三元运算符 键盘输入 fmt.scanln 会在换行时扫描,所以最后一个条目必须换行或达到结束位置 fmt. ...
- .Net与其他公司接口对接心得
第一次搞这玩意,心里有点紧张,万事开头难,第一次搞过之后,以后就容易了,所以将这次经历记录下来. 这里我们暂且把对接的公司叫A吧,A公司会提供一个接口对接说明,下面是A公司提供的接口说明 请求内容说明 ...
- Web基础--JavaScript入门
一.JavaScript 1.什么是JavaScript(JS) (1)JavaScript是嵌入HTML中的代码,在浏览器中执行的脚本语言,具有与Java和C语言类似的语法.(2)一种网页编程技术, ...
- 从 http协议角度解析okhttp
Okhttp 介绍 OkHttp 是 Square 公司开源的一款网络框架,封装了一个高性能的 http 请求库. 支持 spdy.http2.0.websocket 等协议 支持同步.异步请求 封装 ...