前言
上一篇我们知道了一个类的生命周期是:加载->验证->准备->解析->初始化->使用->卸载。
当初始化完成以后,一个类所有的类变量(被static修饰的变量)都被赋值。但是未被static修饰的成员变量又是何时被赋值的呢?
一个类何时会被初始化
一个类何时被初始化可以分为以下几类:
我们来说道说道第3点和第6点
我们平常在使用main方法和调用某个类的静态方法的时候,是不是发现,并不能直接调用静态方法和main方法所在类的非静态方法和非静态变量。
可是明明不是说了在调用静态方法和执行main方法的时候,所在的类已经被初始化了吗?
是的!在上一章节我们就说,类初始化的时候会按照我们编写代码的顺序为类变量(static修饰的变量)进行赋值。注意哦,此时这个类仅仅只有静态变量被正确赋值了哦。
public class People{ private static String name ="lisi"; private int age = 18; static{ name ="zhangsan"; } }
如上述代码,在该类被初始化之后,首先按照代码顺序将类变量(被static修饰的变量)赋值。所以name被赋值"lishi",然后再将name赋值为 "zhangsan"。此时age并没有值,直接直接调用会报错。
一个类何时被实例化
上一个章节中,我们明白了加载->验证->准备->解析->初始化的具体细节。
当初始化完成后,一个类的静态变量被正确赋值。如果这个对象是被new出来的。那么在初始化完成之后会进入实例化阶段。
实例化的具体步骤为:
父类非静态成员初始化语句(包括代码块,按照在类定义中的顺序执行)->父类构造函数->子类非静态成员初始化语句(包括代码块,按照在类定义中的顺序执行)->子类构造方法()
注意哦!
如果这个类有父类不光是先实例化父类。整体流程如下:
1. 加载父类
1.1 为静态属性分配存储空间并赋初始值
1.2 执行静态初始化块和静态初始化语句(从上至下)
2. 加载子类
2.1 为静态属性分配存储空间
2.2 执行静态初始化块和静态初始化语句(从上至下)
3. 加载父类构造器
3.1 为实例属性分配存数空间并赋初始值
3.2 执行实例初始化块和实例初始化语句
3.3 执行构造器内容
4. 加载子类构造器
4.1 为实例属性分配存数空间并赋初始值
4.2 执行实例初始化块和实例初始化语句
4.3 执行构造器内容
实例化的内存模型
到这里,我们就非常的清楚为什么在静态方法中不能直接调用非静态的变量,因为此时的非静态变量并没有被赋值。
以前我在学习的时候,new一个对象出来大家总是在说,我们初始化了这个对象,然后balabala。。。
导致我对于初始化和实例化里的静态变量和非静态变量何时被赋值一直有点模糊。new一个对象出来准确的来说是进行了初始化和实例化两个步骤,这样应该就会清晰了很多。
初始化完成以后,类被存放在方法区,注意哦,此时并没有存放在堆内存中。
只有当对象实例化进入堆内存中以后才会对非静态变量进行初始化赋值。
总结
这下总算吧一个类的初始化和实例化的细节搞明白了,关于文中的方法区,堆内存等内容,下一节再具体分析。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍简单了解JAVA变量类型及代码实例,包括了简单了解JAVA变量类型及代码实例的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了简单了解JAVA变量类型及代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在Java语言中,有类变量、实例变量、局部变量,所有的变量在使用前必须声明。声明普通变量如下: 类变量 类变量也称为
本文向大家介绍Android Build类的详解及简单实例,包括了Android Build类的详解及简单实例的使用技巧和注意事项,需要的朋友参考一下 Android Build类的详解及简单实例 一、类结构: 二、类概述:从系统属性中提取设备硬件和版本信息。 三、内部类: 1、Build.VERSION 各种版本字符串 2、Build.VERSION_CODES 目前已知的版本代码的枚举类 四、
本文向大家介绍C++ 静态成员的类内初始化详解及实例代码,包括了C++ 静态成员的类内初始化详解及实例代码的使用技巧和注意事项,需要的朋友参考一下 C++ 静态成员的类内初始化详解及实例代码 一般来说,关于C++类静态成员的初始化,并不会让人感到难以理解,但是提到C++ 静态成员的"类内初始化"那就容易迷糊了。 我们来看如下代码: 我们需要判断上面的静态数据成员的声明和定义有没有错误,并解释原因。
本文向大家介绍Java中初始化块详解及实例代码,包括了Java中初始化块详解及实例代码的使用技巧和注意事项,需要的朋友参考一下 Java中初始化块详解 在Java中,有两种初始化块:静态初始化块和非静态初始化块. 静态初始化块:使用static定义,当类装载到系统时执行一次.若在静态初始化块中想初始化变量,那仅能初始化类变量,即static修饰的数据成员. 非静态初始化块:在每个对象生成时都会被执
本文向大家介绍简单了解JAVA中类、实例与Class对象,包括了简单了解JAVA中类、实例与Class对象的使用技巧和注意事项,需要的朋友参考一下 类 类是面向对象编程语言的一个重要概念,它是对一项事物的抽象概括,可以包含该事物的一些属性定义,以及操作属性的方法。面向对象编程中,我们都是以类来编码。 实例 简单理解,就是new,就是对类的实例化,创建这个类对应的实际对象,类只是对事物的描述,而实例
我找不到任何关于这个具体案例的具体SO帖子,所以我想问一下我认为是/否的问题。 以下是JLS§12.4.2(Java SE 8),清单6-7: 我的问题是:这是否意味着子类的final static变量在超类的静态初始化之前初始化(假设final static作为其声明的一部分初始化)?