【转载】java基础---静态变量,成员变量,局部变量及类的初始化顺序

时间:2022-01-23 22:00:12

转载自:https://blog.csdn.net/hla199106/article/details/44965315


类变量(也叫静态变量):是类中独立于方法之外的变量,用 static 修饰。(static 表示“全局的”、“静态的”,用来修饰成员变量和成员方法,或静态代码块(静态代码块独立于类成员,jvm 加载类时会执行静态代码块,每个代码块只执行一次,按顺序执行))。


成员变量(也叫“实例变量”、“域”):也是类中独立于方法之外的变量,不过没有 static 修饰。在实体类或数据类中被称为“属性”或“字段”。当成员变量可以改变时,被称为对象的状态。


局部变量:是类的方法中的变量。


常量:用 final 修饰,值一旦给定就不能修改

public class Variable{
     static int allClicks=0;//类变量
     String str="hello world";//实例变量
     public void method(){
        int i =0;//局部变量
     }
}




成员变量和局部变量的区别:


区别一:定义的位置不同。
成员变量定义在类中,在整个类中都可以被访问。
局部变量只定义在局部范围内,如:函数内,语句内等。

区别二:在内存中的位置不同。
成员变量存在于对象所在的堆内存中。
局部变量存在于栈内存中。

区别三:生命周期不同。
成员变量随着对象的建立而建立,随着对象的消失而消失。
局部变量随着方法的运行而出现,随着方法的弹栈而消失。

区别四:初始化不同
成员变量因为在堆内存中,所以有默认初始化值。
局部变量没有默认初始化值。必须初始化后才能使用。


静态变量与成员变量的区别:

1.所属范围不同
静态变量所属于类,成员变量所属于对象。
静态变量也称为:类变量  成员变量也称为:实例变量

2.调用不同
静态变量可以被对象和类名调用(一般用类名调用)
成员变量只能被对象调用

3.加载时期不同
静态变量随着类的加载而加载
成员变量随着对象的加载而加载

4.内存的存储区域不同
静态变量存储在方法区
成员变量存储在堆内存


类初始化顺序


规律一、初始化构造时,先父后子;只有在父类所有都构造完后子类才被初始化

规律二、类加载先是静态、后非静态、最后是构造函数

静态构造块、静态类属性按出现在类定义里面的先后顺序初始化
,同理非静态的也是一样的,只是静态的只在加载字节码是执行一次,不管你new多少次,非静态会在 new 多少次就执行多少次

规律三、java 中的类只有在被用到的时候才会被加载

规律四、java 类只有在类字节码被加载后才可以被构造成对象实例

类初始化化是分,静态,和非静态,静态是在类的字节码加载到 jvm 时,仅且只执行一次,按照先父后子,父子静态都初始化完后,跟据需要再初始化父子非静态部分(也就是说静态和非静态是分开的,但往往因为 new 的时候类即加载类同时也申请内存空间,可以先通过类名加静态方法或者静态属性代码调用来分开两个过程)。


对于普通的 Java 程序,一般都不需要显式的声明来动态加载 Java 类,只需要用 import 关键字将相关联的类引入,类被第一次调用的时候,就会被加载初始化。那对于一个类对象,其内部各组成部分的初始化顺序又是如何的呢?

一个 Java 类对象在初始化的时候必定是按照一定顺序初始化其静态块、静态属性、类内部属性、构造方法。这里我们讨论的初始化分别针对两个对象
一个是类本身还有一个是类实例化的对象。

类本身的初始化会在类被加载完毕、链接完成之后,由 Java 虚拟机负责调用 <clinit> 方法完成。在这个方法中依次完成了堆类内部静态块的调用和类内部静态属性的初始化(如果存在父类,父类会优先进行初始化)。不论创建多少个实例化的对象,一个类只会被初始化一次。

类实例化的对象通过 new 操作创建,Java 虚拟机保证一个类在 new 操作实例化其对象之前已经完成了类的加载、链接和初始化。之后 Java 虚拟机会调用 <init> 方法完成类实例化对象的初始化。这个方法会优先按照代码中顺序完成对类内部个属性的初始化,之后再调用类的构造函数(如果有父类,则优先调用父类的构造函数)。

PS:需要注意的是上述提到的 <init> 和 <clinit> 方法都是非法的 Java 方法名,是由编译器命名的,并不能由编码实现。

综上所述,我们大致可以得出以下结论,对于一个类,在实例化一个这个类的对象时,我们可以保证以下这样的优先级进行初始化:

类内部静态块 = 类静态属性(静态构造块、静态类属性按出现在类定义里面的先后顺序初始化) > 类内部属性 > 类构造函数

内部类:
内部类静态属性(或静态块)会在内部类第一次被调用的时候按顺序被初始化(或执行);而类内部静态块的执行先于类内部静态属性的初始化,会发生在类被第一次加载初始化的时候;类内部属性的初始化先于构造函数会发生在一个类的对象被实例化的时候。




参考文章:  

java易混淆概念之类变量、成员变量、局部变量  

Java杂谈3——类加载机制与初始化顺序