Java基础(012):静态变量和实例变量以及局部变量的区别
注:有需要的可以进一步关注Java中关于 [4]8.2. Class Members 相关说明。
在Java中,变量([1]Declaring Member Variables 和 [2]Variables )包括以下几种:
- 成员变量,包括静态变量和实例变量,是在类中定义的,通过 static 关键字区分,也称为属性 field局部变量 local variables:方法中定义的临时变量
- 静态变量/类变量, class variables (or static variables),属于类,类加载时会同时进行加载,只有唯一的一份。
- 实例变量 instance variables:属于实例,实例化时会都会初始化一次,是实例独有的。
- 局部变量 local variables:方法中定义的临时变量
- 方法参数:方法定义中的参数列表中涉及到的变量
以下是一些相关的总结:
比较点 | 静态变量/类变量 | 实例变量 | 局部变量 |
---|---|---|---|
语法定义 |
在类中声明且使用 也称为类变量(class variables),还可以用访问权限修饰符和final修饰 |
和类变量声明类似,区别在于没有 static 修饰 |
|
定义位置 | 在类中,但是在方法、构造器、语句块之外,声明上是独立存在的 | 一样 | 方法内部、构造器或者语句块中(静态代码块和非静态代码块) |
存放位置 | 方法区 | 堆 (不包括栈上分配、标量替换等) | 栈 + 堆(对象) |
加载时机 |
类加载时进行唯一的一次内存分配,除非类加载器重新加载, 否则不会再分配内存,在类加载器层面只有这一个共享的 |
实例化的时候分配内存 | 语句执行时(声明+初始化/赋值)进行分配 |
运行时/生命周期 |
与类绑定,随着类加载而初始化,随着类卸载而回收。静态变量是类层面的, 只要类加载器加载了对应的类,静态变量就已经分配内存了,也即是说,在 加载类的过程中完成静态变量的内存分配,而且只有一次。静态变量不用创 建任何实例对象可以被直接使用,在类加载器层面是唯一的,所有实例共享, 一般是直接通过类名来进行引用。 |
实例变量随着对象的实例化创建而分配,随着对象的消失而回收。实例变量是类实例层面的, 是具体实例的一个属性,只有类实例化分配内存后才会存在,才可以通过实例对象的引用来 进行访问使用。每次实例化都会新分配一次内存,实例变量依赖于对应的具体实例,而且在 每个实例对象中是唯一的,不共享。 |
一般随着方法调用结束而销毁,除非作为结果返回或者中间作为外层变量的属性等,生命周期会扩大 |
作用域 | 类加载时就存在,类卸载时回收 | 实例化时存在,随着实例被回收而消失 | 对应的语句块内部,一般是在最近的{}内部 |
调用方式 | 一般通过类名直接引用,如 ClassName.StaticVariableName |
通过实例对象进行引用 | 在作用域之内直接引用,一般建议哪里使用就在哪里声明 |
可见性 | public/(default)/protected/private (访问权限修饰符) | 一样 | / |
final 修饰 |
一般都当作是全局常量,而且建议全大写的命名方式 |
只初始化一次,后续不能再修改(对象不能重新引用,原始数据类型不能修改值),当作是引 用值(内部属性可能可以修改)或者原始数据类型值不可变 |
同样只能初始化一次 |
初始化/默认值 | 数值型变量默认值为 0,布尔型默认值为 false ,引用类型默认值为 null |
一样 | 无默认值,需要强制初始化 |
共享和并发问题 | 静态变量是共享的,多线程写会存在并发问题,建议尽量使用不可变对象或者常量 | 实例独有,有可能存在并发修改问题 | |
使用建议 | 静态常量、不可变对象 | 哪里用到就在哪里声明 |
参考:
- [1]Declaring Member Variables https://docs.oracle.com/javase/tutorial/java/javaOO/variables.html
- [2]Variables https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html
- [3]Understanding Class Members https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
- [4]8.2. Class Members https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2
- [5]CLASS VARIABLES, INSTANCE VARIABLES AND LOCAL VARIABLES IN JAVA https://www.javajee.com/class-variables-instance-variables-and-local-variables-in-java