JAVA的成员变量和局部变量(详解)



JAVA的变量可以分为两大类:成员变量局部变量

成员变量与局部变量的分类

具体细分,成员变量可以分为两类:实例变量类变量
局部变量可以分为三类:形参方法局部变量代码块局部变量
如下图所示:
在这里插入图片描述



实例变量与类变量的区别

这两种变量很好区别,与某个实例(对象)有关的成员变量就是实例变量与整个类有关的成员变量就是类变量
类变量和实例变量有以下不同:
1.生存周期不同
类变量是在类的准备阶段被创建,此时系统还没有创建对应的对象。所以,类变量的创建早于实例变量类变量会在类销毁时一同被销毁,而实例变量是在对应对象被销毁时一同被销毁。因为类一定在所有对象都被销毁时才被销毁,所以类变量的死亡时间也晚于实例变量
可以概括为:类变量的生存周期与类的生存周期基本相同,实例变量的生存周期与对应对象的生存周期基本相同

2.访问方式不同
访问类变量的语法为:类.类变量名
访问实例变量的语法为:引用变量名.实例变量名
虽然说类变量也可以用引用变量名.类变量名的方式访问,但访问的类变量本身并不与该对象相关,在java底层,这种方式也会被替换为:类.类变量名的访问方式。所以本质这种访问方式是java的不良设计,是不推荐的。

3.作用范围不同
类变量是所有对象共有的,所有对象访问类变量,都是访问的同一块内存区域。所以,类变量的作用范围是整个类。而实例变量是某个对象独有的,它是某个对象的状态属性,改变某个对象的实例变量,不会影响到其他对象。

4.内存中的存储位置不同
类变量是存储在与类有关的单独的区域,所有对象访问类变量时,都是访问的这一块区域。而实例变量是存储在自身对象所在的那块区域,每个对象都需要有自身的一块区域存储自身的实例变量。



三种局部变量的区别

局部变量根据定义位置的不同,可以分为三类:
1.形参:在定义方法签名时定义的变量。
2.方法局部变量:在方法体内定义的变量。
3.代码块局部变量:在代码块中定义的局部变量。

下面来讲解它们的区别
1.是否需要显式初始化
只有形参不需要显式初始化,因为形参的初始化在调用对应方法时,由调用者传递的参数来完成。方法局部变量和代码块局部变量都需要显式初始化仅仅定义这两种局部变量,但不初始化,系统不会在内存中生成对应的空间,必须进行显式初始化后,这两种局部变量才会在内存中有具体的空间存储值。

2.作用域和生存周期不同
形参:在整个方法内有效。
方法局部变量:从初始化该变量到方法结束为止都有效。
代码块局部变量:从在代码块中初始化到代码块结束为止都有效。



成员变量与局部变量的区别

有以下区别:
1.系统是否会默认初始化
对于成员变量,系统会在类生成或者对象创建阶段自动为其初始化,即使成员变量没有显式赋值,系统也会为其分配内存空间并且附上零值。但局部变量除了形参外必须显式初始化(形参的初始化是调用者通过实参值传递完成的),否则系统不会为其分配内存空间。

2.在内存中的位置不同
成员变量存储在堆内存中,与对应的类或者对象绑定。而局部变量与方法绑定,一同存储在栈内存中,方法执行结束,所有局部变量都会被销毁(代码块局部变量会在代码块结束就出栈销毁)。



变量同名问题

我们最好避免变量同名,但有的时候也会出现变量同名的情况。
以下是变量同名的规则:
1.成员变量与局部变量同名
此时,成员变量会被局部变量覆盖,也就是成员变量虽然存在,但是无法在该方法内起作用。如果要在该方法内使用被覆盖的成员变量,必须使用this或者类名作为调用者来限定访问。加上了主调,程序就能分辨出该变量是成员变量。

2.成员变量之间同名不允许
哪怕一个是类变量一个是实例变量,只要同名都是不允许的,否则会出现程序的歧义。

3.方法局部变量之间不能同名,形参之间也不能同名,方法局部变量也不能和形参同名
其实很好理解,因为它们的生存周期重叠了,如果同名,系统不知道你到底要访问的是哪一块内存区域。

4.不同代码块内的代码块局部变量可以同名
这是因为代码块结束,代码块局部变量就死亡了,所以它们的生存周期是不重合的,就不会产生歧义。

5.如果先定义代码块局部变量,再定义方法局部变量,允许
这也是生存周期不重合导致的,代码块局部变量先死亡,后面的同名方法局部变量不会产生分歧。



变量的使用规则

虽然直接定义成员变量就可以解决问题,但是胡乱使用成员变量会让程序变得混乱。
成员变量有更大的作用域和生存周期,不利于程序的内聚性,而且带来的开销也大得多
程序希望各个模块之间的影响越少越好,所以能使用方法局部变量就不要使用成员变量,能使用代码块局部变量就不要使用方法局部变量。

何时使用成员变量

满足以下条件之一就可以考虑使用成员变量:
1.该变量用于描述某个类或者对象的固有信息,例如身高、体重等。

2.该变量用于保存类或者实例运行时的实时状态,比如五子棋的棋盘信息,会随着下棋进程不断改变,这种信息自然和类或者对象绑定。

3.如果某个变量的值会在多个方法之间共享,则应该使用成员变量。

猜你喜欢

转载自blog.csdn.net/qq_983030560/article/details/130895152