面试官:为什么java中静态方法不能调用非静态方法和变量?

这个可能很多人之前学习jvm的时候都会遇到,属于一个小问题,写这篇文章的原因是我在看java相关的面试题目中遇到的,因此顺手总结一下:

一、例子

我们先看效果:



我们在静态方法main中调用非静态变量或者是方法都会报错。我们反过来看看:



反过来没有一点问题,接下来我们解释一下原因:

二、原因解释

我们需要首先知道的是静态方法和静态变量是属于某一个类,而不属于类的对象。我们不直接讲原因,先从jvm说起:



这是一张类加载的生命周期图。

1、加载

”加载“是”类加机制”的第一个过程,在加载阶段,虚拟机主要完成三件事:

(1)通过一个类的全限定名来获取其定义的二进制字节流

(2)将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构

(3)在堆中生成一个代表这个类的Class对象,作为方法区中这些数据的访问入口。

注意此时会扫描到我们的代码中是否有静态变量或者是静态方法等等这些静态数据结构,还未分配内存。

2、验证

验证的主要作用就是确保被加载的类的正确性。

3、准备

准备阶段主要为类变量分配内存并设置初始值。这些内存都在方法区分配。注意此时就会为我们的类变量也就是静态变量分配内存,但是普通成员变量还没。

4、解析

解析阶段主要是虚拟机将常量池中的符号引用转化为直接引用的过程。

5、初始化

这是类加载机制的最后一步,在这个阶段,java程序代码才开始真正执行。我们知道,在准备阶段已经为类变量赋过一次值。在初始化阶端,程序员可以根据自己的需求来赋值了。初始化时候才会为我们的普通成员变量赋值。

写到这答案已经出来了,静态方法是属于类的,动态方法属于实例对象,在类加载的时候就会分配内存,可以 通过类名直接去访问,非静态成员(变量和方法)属于类的对象,所以只有该对象初始化之后才存在,然后通过类的对象去访问。

也就是说如果我们在静态方法中调用非静态成员变量会超前,可能会调用了一个还未初始化的变量。因此编译器会报错。

相关文章

Java 中的静态字段和静态方法

还记得我们写的第一个 Java 代码吗?public class Main { public static void main(String[] args) { System....

Java类中静态方法和静态变量,静态代码块,构造方法执行顺序

一,Java类执行顺序子类:ATest父类:AParentTest直接调用静态方法第一种:当直接调用(没有new对象)静态方法时候:父类静态变量(按照顺序)执行----->子类静态变量(按照顺序...

Java程序员必备技能:静态方法的正确使用姿势!

“静态方法是Java中的一种方法,它属于类而不是类的实例,这意味着你可以在不创建类的实例的情况下调用它,直接通过类名来访问,静态方法在内存中只有一份,无论该类被实例化多少次,它的静态方法都只有一份。”...

Java:什么是静态代理?什么是动态代理?二者有何区别?

推荐学习微服务架构秘籍:SpringCloud+SpringCloud Alibaba,全网疯传肝了30天,整出这份[分布式宝典:限流+缓存+通讯],秋招跳槽有望听说你很懂源码?Spring读懂了?还...

为何要在Java中使用静态类?

在Java中,static关键字可以被用于变量,类,代码块和方法。当我们使用static关键字去修饰它们之中的任何一个时,意味着这个指定的成员从属与这个类型本身。换言之, 一个静态成员被创建完成后可以...