美文网首页
为什么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