类加载准备阶段 类变量赋值


关键词

  • 加载阶段>链接阶段(验证,准备,解析)>初始化阶段
  • 在链接得准备阶段进行静态变量得默认值赋值操作

一、面试题:请回答,下面两段代码得执行结果

public class A {static int a ;public static void main(String[] args) {System.out.println(a);}}
public class B {public static void main(String[] args) {int a ;System.out.println(a);}}

二、回答

  • 程序1:输出 0
  • 程序2:无法通过编译

三、剖析

1. 类加载子系统介绍


1、类加载子系统负责从文件系统或是网络中加载.class文件,class文件在文件开头有特定的文件标识。

2、把加载后的class类信息存放于方法区,除了类信息之外,方法区还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射);

3、ClassLoader 只负责class文件的加载 ,至于它是否可以运行,则由Execution Engine决定;

4、如果调用构造器实例化对象,则该对象存放在堆区;

2. 类加载的执行过程

我们写的程序经过编译后成为了.class文件,.class文件中描述了类的各种信息,最终都需要加载到虚拟机之后才能运行和使用。而虚拟机如何加载这些.class文件?.class文件的信息进入到虚拟机后会发生什么变化

类使用的7个阶段
类从被加载到虚拟机内存中开始,到卸载出内存,它的整个生命周期包括:

  • 加载(Loading)、
  • 验证(Verification)、
  • 准备(Preparation)、
  • 解析(Resolution)、
  • 初始化(Initiallization)、
  • 使用(Using)
  • 卸载(Unloading)

这7个阶段。其中验证、准备、解析3个部分统称为连接(Linking)

3. 加载

加载是类加载的第一个阶段。有两种时机会触发类加载:

1)预加载

虚拟机启动时加载,加载的是JAVA_HOME/lib/下的rt.jar下的.class文件,这个jar包里面的内容是程序运行时非常常常用到的,像java.lang.*、java.util.、 java.io. 等等,因此随着虚拟机一起加载。

2)运行时加载

虚拟机在用到一个.class文件的时候,会先去内存中查看一下这个.class文件有没有被加载,如果没有就会按照类的全限定名来加载这个类。

那么,加载阶段做了什么,其实加载阶段做了有三件事情:

  • 获取.class文件的二进制流
  • 将类信息、静态变量、字节码、常量这些.class文件中的内容放入方法区中
  • 在内存中生成一个代表这个.class文件的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。一般这个Class是在堆里的,不过HotSpot虚拟机比较特殊,这个Class对象是放在方法区中的

4. 链接( 面试题得考点 )

链接包含三个步骤: 分别是 验证Verification , 准备Preparation , 解析Resolution 三个过程

1)验证Verification

连接阶段的第一步,这一阶段的目的是为了确保.class文件的字节流中包含的信息符合当前虚拟机的要求,并且
会危害虚拟机自身的安全

Java语言本身是相对安全的语言(相对C/C++来说),但是前面说过,.class文件未必要从Java源码编译而来,可以使用任何途径产生,甚至包括用十六进制编辑器直接编写来产生.class文件。在字节码语言层面上,Java代码至少从语义上是可以表达出来的。虚拟机如果不检查输入的字节流,对其完全信任的话,很可能会因为载入了有害的字节流而导致系统崩溃,所以验证是虚拟机对自身保护的一项重要工作。

验证阶段将做一下几个工作,具体就不细讲了,这是虚拟机实现层面的问题:

  • 文件格式验证

  • 元数据验证

  • 字节码验证

  • 符号引用验证

2)准备Preparation

准备阶段是正式为类变量分配内存并设置其初始值的阶段,这些变量所使用的内存都将在方法区中分配。关于这点,有两个地方注意一下:

  • 这时候进行内存分配的仅仅是类变量(被static修饰的变量),而不是实例变量,实例变量将会在对象实例化的时候随着对象一起分配在Java堆中
  • 这个阶段赋初始值的变量指的是那些不被final修饰的static变量,比如"public static int value = 666",value在准备阶段过后是0而不是666,给value赋值为666的动作将在初始化阶段才进行;比如"public static final int value =666;"就不一样了,在准备阶段,虚拟机就会给value赋值为666。

注意 :
这是因为局部变量不像类变量那样存在准备阶段
类变量有两次赋初始值的过程

  • 一次在准备阶段,赋予初始值(也可以是指定值)
  • 另外一次在初始化阶段,赋予程序员定义的值

因此,即使程序员没有为类变量赋值也没有关系,它仍然有一个默认的初始值。但局部变量就不一样了,如果没有给它赋初始值,是不能使用的。

四、总结

  • 类变量在准备阶段进行了默认值赋值操作,后续初始化阶段不进行赋值操作也有默认值,因此程序可以正常运行
  • 局部变量在准备阶段不会进行初始值操作,后续初始化阶段也不赋值则不能使用,编译失败

面试题:为什么局部变量不赋初始值报错相关推荐

  1. 注意:C语言结构体里不能赋初始值!

    创建结构体只是开辟了一块内存空间,而不赋初始值,赋初始值有的编译器不支持的! 啥时候能赋初始值呢,c++11 可见:C++ 之设置struct 属性的默认值 C++ 11结构体内直接赋初始值

  2. layui select日期_layui给下拉框、按钮状态、时间赋初始值的方法,按钮的状态

    layui给下拉框.按钮状态.时间赋初始值的方法,按钮的状态 如下所示: 编辑 layui.use('table', function() { var table = layui.table; //监 ...

  3. layui select日期_layui给下拉框、按钮状态、时间赋初始值的方法

    如下所示: 编辑 layui.use('table', function() { var table = layui.table; //监听行工具事件 table.on('tool(test)', f ...

  4. 属性赋初始值的四种写法--C#6.0新特性

    1 介绍 在C# 6.0 语法出来前,属性的赋初始值使用get:set:虽然已经相对于最原始的写法简洁了非常多,但是还不够,还不够,还不够...今天刚好一直在想着前几天朋友问我的有关属性赋初始值的问题 ...

  5. {__ob__: observer}取值报错问题

    {ob: observer}取值报错问题 解决方案:JSON.parse(JSON.stringify( ob )) 在直接对{ob: observer}访问属性时会报错,网上看到的大多数人是报und ...

  6. go 定义一个结构体并赋初始值_Go中必须谈论的四个迷点

    很多熟悉Go的程序员们都会说到Go是一门很简单的语言,话虽如此,但实际上Go的简单是基于复杂底层的极简包装. Go在很多地方均做了"隐式"的转换,这也就导致了很多迷惑点,本文总结了 ...

  7. 如何给dropdownlist动态赋初始值_清华大学 林弋莎、鲁宗相、乔颖等:如何考虑预测信息完备程度和风水资源互补性特点,实现高比例可再生能源系统中长期计划优化?...

    <电网技术>,值得信赖的电力学术期刊 戳题目,看全文! 考虑中长期电量不确定性的可再生能源系统嵌套运行优化/林弋莎,孙荣富,鲁宗相,乔颖 <电网技术>2020年第9期:3272 ...

  8. 一道经典面试题讲解 :数组越界而没报错 ,却出现死循环 ?(C语言)

    下面这道经典易错题出自<C陷阱与缺陷>,也一度被众多互联网公司作为面试题拿来考察,可见其易错程度与重点程度,下面我就给大家详细讲解一下这道列题,希望对大家有所帮助: 作为面试题: 下面我们 ...

  9. python全局变量有缩进吗_Python全局变量和局部变量的问题 400 请求报错 -问答-阿里云开发者社区-阿里云...

    # coding:utf-8 sum = 5 def add(x, y): print sum sum = x + y if __name__ == '__main__': add(7, 8) 上面的 ...

最新文章

  1. Spring boot的Restful风格CRUD
  2. SpringBoot项目优化和Jvm调优(楼主亲测,真实有效)
  3. Loadrunner性能测试结果分析
  4. python 验证数据类型函数
  5. css如何将元素水平居中
  6. Python库:Pyinstaller库、pip工具、pip指定安装源和版本
  7. 霍夫变换检测直线的公式推导以及基于opencv的源代码分析并实例实现
  8. LINUX查询版本情况
  9. Java导出导入Excel方法
  10. 全球首个中文PaaS支撑平台----天翎myApps快速开发平台
  11. u3d 100道面试题(包含答案)
  12. 德州仪器发布99%高效GaN逆变器功率级的参考设计
  13. revo uninstaller pro 长期试用的正确姿势!!
  14. ThreeJS - 动态更换fbx模型的某个子Mesh现有的纹理贴图为指定的纹理贴图
  15. linux 软件覆盖安装,pacman/yaourt安装软件的时候覆盖了/usr/share的symlink链接的问题...
  16. 《加州消费者隐私法案》(CCPA)解读一:美国最严隐私法CCPA适用范围有哪些?
  17. lab值意义_色差仪lab值含义是什么?
  18. ckeditor5快速使用
  19. 什么是电商ERP,有什么作用
  20. 圣诞树有手就行的c语言代码

热门文章

  1. Android 使用webview遇到的问题及解决办法
  2. appearance—外观样式属性
  3. ipmi对于统一硬件管理的意义
  4. docker创建image
  5. Java编写的测试加法计算的工具
  6. 更新MYSQL生成日历表,支持跨年份 存储过程
  7. 30岁之前创业成功的12个要点
  8. 网关 Apache APISIX 在 360 基础运维平台项目中的实践
  9. MongoDB 新功能介绍-Change Streams
  10. flink的MemorySegment