美文网首页
为什么Java静态方法中不能调用非静态内容

为什么Java静态方法中不能调用非静态内容

作者: MrEthanLee | 来源:发表于2020-06-15 10:37 被阅读0次

参考自:[https://blog.csdn.net/ns_code/article/details/17881581]

重点

  1. 程序均在内存中执行,变量(方法)只有存放于内存中时,才能被访问
  2. 类的静态成员(变量或方法)属于类本身,在类加载的时候就会分配内存,可以通过类名直接去访问。
  3. 非静态成员(变量和方法)属于类的对象,只有在类的对象产生时(创建实例-new)才会分配内存,然后通过实例去访问。

类加载过程

类从被加载到虚拟机中开始,到卸载出内存为止,整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。如图所示:

Image.png
其中类加载的过程中包括了加载、验证、准备、解析、初始化五个阶段。
这五个阶段除了解析其他四个阶段发生的顺序是确定的,解析阶段在某些情况下考研在初始化阶段之后,是为了支持Java语言的运行时绑定(也称为动态绑定或晚期绑定)。
Note:这几个阶段是顺序开始,并不是顺序进行顺序完成。通常是互相交叉混合进行,在一个阶段的执行过程中调用或激活另一个阶段。
Java中绑定:把一个方法的调用与方法所在的类关联起来,分为静态和动态绑定。
  • 静态绑定:前期绑定。在程序执行前已经绑定。java中只有final、static、private和构造方法是前期绑定的。
  • 动态绑定:即晚期绑定或运行绑定。在java中,几乎所有的方法都是后期绑定的。

准备阶段

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中分配。对于该阶段有以下几点需要注意:

  • 这时候进行内存分配的仅包括类变量(static),而不包括实例变量,实例变量会在对象实例化时随着对象一块分配在Java堆中。
  • 这里所设置的初始值通常情况下是数据类型默认的零值(如0、0L、null、false等),而不是被在Java代码中被显式地赋予的值。

假设一个类别量定义为:

public static int value = 3

那么变量value在准备阶段过后的初始值为0,而不是3,因为这个时候未执行任何java方法,而把value赋值为3的putstatic指令是在程序编译后,存放于类构造器<clinit>()方法之中的,所以把value赋值为3的动作将在初始化阶段才会执行

Java中所有基本数据类型以及reference类型的默认零值:

数据类型 默认零值
int 0
long 0L

Note:

  • 对基本数据类型来说,对于类变量(static)和全局变量,如果不显式地对其赋值而直接使用,则系统会为其赋予默认的零值,而对于局部变量来说,在使用前必须显式地为其赋值,否则编译时不通过。
  • 对于同时被static和final修饰的常量,必须在声明的时候就为其显式地赋值,否则编译时不通过;而只被final修饰的常量则既可以在声明时显式地为其赋值,也可以在类初始化时显式地为其赋值,总之,在使用前必须为其显式地赋值,系统不会为其赋予默认零值。
  • 对于引用数据类型reference来说,如数组引用、对象引用等,如果没有对其进行显式地赋值而直接使用,系统都会为其赋予默认的零值,即null。
  • 如果在数组初始化时没有对数组中的各元素赋值,那么其中的元素将根据对应的数据类型而被赋予默认的零值。

相关文章

网友评论

      本文标题:为什么Java静态方法中不能调用非静态内容

      本文链接:https://www.haomeiwen.com/subject/adrcxktx.html