为什么Java中静态方法不能调用非静态方法和变量?

这个问题在学习jvm的时候会遇到过

首先看个例子
一 例子
我们先看效果
效果
在这里插入图片描述
我们在静态方法main中调用非静态变量或者是方法都会报错。我们反过来看看
在这里插入图片描述
反过来没有问题,这是什么原因呢?

二、原因解释
我们需要首先知道的是静态方法和静态变量是属于某一个类,而不是属于类的对象。先从jvm说起:
在这里插入图片描述
这是一张类加载的生命周期图
1、加载:
加载是“类加机制”的第一个过程,在加载阶段,虚拟机主要完成三件事情:
(1) 通过一个类的全限定名类获取其定义的二进制字节流
(2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
(3)在堆中生成一个代表这个类的Class对象,作为方法区中这些数据的访问入口。

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

2、 验证

验证的主要做那个是确保被加载的类的正确性。

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

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

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

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

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

猜你喜欢

转载自blog.csdn.net/damokelisijian866/article/details/104762687
今日推荐