网站首页 > java教程 正文
这个可能很多人之前学习jvm的时候都会遇到,属于一个小问题,写这篇文章的原因是我在看java相关的面试题目中遇到的,因此顺手总结一下:
一、例子
我们先看效果:
我们在静态方法main中调用非静态变量或者是方法都会报错。我们反过来看看:
反过来没有一点问题,接下来我们解释一下原因:
二、原因解释
我们需要首先知道的是静态方法和静态变量是属于某一个类,而不属于类的对象。我们不直接讲原因,先从jvm说起:
这是一张类加载的生命周期图。
1、加载
”加载“是”类加机制”的第一个过程,在加载阶段,虚拟机主要完成三件事:
(1)通过一个类的全限定名来获取其定义的二进制字节流
(2)将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构
(3)在堆中生成一个代表这个类的Class对象,作为方法区中这些数据的访问入口。
注意此时会扫描到我们的代码中是否有静态变量或者是静态方法等等这些静态数据结构,还未分配内存。
2、验证
验证的主要作用就是确保被加载的类的正确性。
3、准备
准备阶段主要为类变量分配内存并设置初始值。这些内存都在方法区分配。注意此时就会为我们的类变量也就是静态变量分配内存,但是普通成员变量还没。
4、解析
解析阶段主要是虚拟机将常量池中的符号引用转化为直接引用的过程。
5、初始化
这是类加载机制的最后一步,在这个阶段,java程序代码才开始真正执行。我们知道,在准备阶段已经为类变量赋过一次值。在初始化阶端,程序员可以根据自己的需求来赋值了。初始化时候才会为我们的普通成员变量赋值。
写到这答案已经出来了,静态方法是属于类的,动态方法属于实例对象,在类加载的时候就会分配内存,可以 通过类名直接去访问,非静态成员(变量和方法)属于类的对象,所以只有该对象初始化之后才存在,然后通过类的对象去访问。
也就是说如果我们在静态方法中调用非静态成员变量会超前,可能会调用了一个还未初始化的变量。因此编译器会报错。
- 上一篇: 你说你是高工,匿名内部类有我玩得6吗?
- 下一篇: Spock单元测试框架系列(六):Mock静态方法
猜你喜欢
- 2024-12-10 Spock单元测试框架系列(六):Mock静态方法
- 2024-12-10 你说你是高工,匿名内部类有我玩得6吗?
- 2024-12-10 详解Java中的静态代理和动态代理
- 2024-12-10 一文讲透父子类中静态变量,成员变量初始化顺序原理
- 2024-12-10 Java错误排行:50种常见bug及如何避免它们(二)
- 2024-12-10 Java中的反射机制:动态调用方法与属性
- 2024-12-10 Java 详细剖析关键字 static,深入全面了解
- 2024-12-10 java静态方法是什么
- 2024-12-10 为何要在Java中使用静态类?
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)