Java Review (八、面向对象—-成员变量和局部变量)

Java Review (八、面向对象—-成员变量和局部变量)

在Java语言中,根据定义变量位置的不同,可以将变量分成两大类:成员变量和局部变量。成员变量和局部变量的运行机制存在较大差异。

成员变量和局部变量是什么

成员变量指的是声明在一个类中,但在方法、构造方法和语句块之外的变量, 局部变量指的是声明在方法、构造方法或者语句块中里的变量。

不管是成员变量还是局部变量,都应该遵守相同的命名规则:从语法角度来看,只要是一个合法的标识符即可;但从程序可读性角度来看,应该遵循驼峰命名法的原则:首个单词首字母小写,后面每个单词首字母大写。

成员变量

Java 程序中的变量划分如图一:变量被分为类变量和实例变量两种,定义成员变量时没有 修饰的就是实例变量,有 修饰的就是类变量。

图一:变量分类

正是基于这个原因,可以把类变量和实例变量统称为成员变量。

只要类存在,程序就可以访问该类的类变量。在程序中访问类变量通过如下语法

类.类变量

只要实例存在,程序就可以访问该实例的实例变量。在程序中访问实例变量通过如下语法:

实例.实例变量

当然,类变量 可以让该类的实例来访问 通过实例来访问类变量的语法如下:

实例.类变量

但由于这个实例并不拥有这个类变量,因此它访问的并不是这个实例的变量,依然是访问它对应类的类变量。

也就是说如果通过一个实例修改了类变量的值,由于这个类变并不属于它,而是属于它对应的类,因此,修改的依然是类的类变量,与通过该类来修改类变量的结果完全相同。

下面程序定义了 类, 在这个类中定义两个成员变量,一个实例变量 name ,以及一个类变量 ,并分别通过 类和 实例来访问实例变量和类变量:

实例一、.java

class Person {
   //定义一个实例变量
	public String name;
   //定义一个类变量
	public static int eyeNum;
}
public class PersonTest {
	public static void main(String[] args) {
   //第一次主动使用Person类,该类自动初始化,则eyeNum变量开始起作用,输出 
		System.out.println("Person 的 eyeNum 类变量值:" + Person.eyeNum);
   //创建Person对象
		Person p = new Person();
   //通过Person对象的引用p来访问Person对象name实例变量
   //并通过实例访问eyeNum类变量
		System.out.println("p变量的 name变量值是:" + p.name + ";p对象的 eyeNum 变量值是:" + p.eyeNum);
    //直接为name实例变量赋值
		p.name = "孙悟空";
     //通过P访问eyeNum类变量,依然是访问Person类的eyeNum类变量
		p.eyeNum = 2;
    //再次通过Person对象来访问name实例变量和eyeNum类变量
		System.out.println("p变量的 name变量值是:" + p.name + ";P 对象的 eyeNum 变量值是:" + p.eyeNum);
     //前面通过P修改了 Person的eyeNum,此处的Person. eyeNum将输出2 
		System.out.println("Person类的 eyeNum 类变量值:" + Person.eyeNum);
		Person p2 = new Person();
    // P2访问的eyeNum类变量依然引用Person类的,因此依然输出2 
		System.out.println("p2对象的 eyeNum类变量值:" + p2.eyeNum);
	}
}

结果:

Person 的 eyeNum 类变量值:0
p变量的 name变量值是:null;p对象的 eyeNum 变量值是:0
p变量的 name变量值是:孙悟空;P 对象的 eyeNum 变量值是:2
Person类的 eyeNum 类变量值:2
p2对象的 eyeNum类变量值:2

成员变量无须显式初始化:只要为一个类定义了类变量或实例变量,系统就会在这个类的准备阶段或创建该类的实例时进行默认初始化,成员变量默认初始化时的赋值规则与数组动态初始化时数组元素的赋值规则完全相同。

类变量的作用域比实例变量的作用域更大:实例变量随实例的 存在而存在,而类变量则随类的存在而存在。实例也可访问类变量Java Review (八、面向对象—-成员变量和局部变量),同一个类的所有实例访问类变量时, 实际上访问的是该类本身的同一个变量,也就是说,访问了同一片内存区。

局部变量

局部变量根据定义形式的不同,又可以被分为如下三种。

与成员变量不同的是,局部变量除了形参之外,都必须显式初始化。也就是说,必须先给方法局部变量和代码块局部变量指定初始值,否则不可以访问它们。

当通过类或对象调用某个方法时,系统会在该方法栈区内为所有的形参分配内存空间,并将实参的值赋给对应的形参,这就完成了形参的初始化。

作用范围与命名

在同一个类里,成员变量的作用范围是整个类内有效,

Java允许局部变量和成员变量同名,如果方法里的局部变量和成员变量同名,局部变量会覆盖成员 变量,如果需要在这个方法里引用被覆盖的成员变量,则可使用this (对于实例变量)或类名(对于类变量)作为调用者来限定访问成员变量。

成员变量的初始化和内存中的运行机制

当系统加载类或创建该类的实例时,系统自动为成员变量分配内存空间,并在分配内存空间后,自动为成员变量指定初始值。

实例二、.java

      //创建第一个Person对象
	   Person pl = new Person();
	   //创建第二个Person对象
	   Person p2 = new Person();
	   //分别对两个Person对象的name实例变量赋值
	   pl.name = "张三";
	   p2.name = "孙悟空";
	   //分别为两个Person对象的eyeNum类变量赋值
	   pl.eyeNum =2;
	   p2.eyeNum = 3;

图一:初始化 类后的存储示意图

从图一中可以看出java方法中的局部变量,当 类初始化完成后,系统将在堆内存中为类分配一块内存区(当 类初始化完成后,系统会为 类创建一个类对象),在这块内存区里包含了保存类变量的内存java方法中的局部变量,并设 置的默认初始值:0。

图二:创建第一个 对象后的存储示意图

从图二中可以看出,类变量并不属于对象,它是属于类的,所以创建第 ―个对象时并不需要为类变量分配内存,系统只是为name实例变量分配了内存空间, 并指定默认初始值:null。

图三:为第一个 对象 name 实例变量赋值后的存储示意图

从图三中可以看出,name实例变量是属于单个实例的,因此修改第一个对象的 name实例变量时仅仅与该对象有关,与类和其他对象没有任何关系。同样,修改第二个 对象的name实例变量时,也与类和其他对象无关。

图四:设置 p1 的 变量之后的存储示意图

从图四中可以看出,当通过p1来访问类变量时,实际上访问的是类的类变量。 事实上,所有的实例访问类变量时都将访问到类的类变量,也就是图四中灰色覆盖的区域,本质其实还是通过类来访问类变量时,访问的是同一块内存。基于这个理由,当程序需要访问类变量时,尽量使用类作为主调,而不要使用对象作为主调,这样可以避免程序产生歧义,提高程序的可读性。

局部变量的初始化和内存中的运行机制

局部变量定义后,必须经过显式初始化后才能使用,系统不会为局部变量执行初始化。这意味着定 义局部变量后,系统并未为这个变量分配内存空间java方法中的局部变量,直到等到程序为这个变量赋初始值时,系统才会为局部变量分配内存,并将初始值保存到这块内存中。

与成员变量不同,局部变量不属于任何类或实例,因此它总是保存在其所在方法的栈内存中。

栈内存中的变量无须系统垃圾回收Java Review (八、面向对象—-成员变量和局部变量),往往随方法或代码块的运行结束而结束。因此,局部变量的作用域是从初始化该变量开始,直到该方法或该代码块运行完成而结束。因为局部变量只保存基本类型的值或者对象的引用,因此局部变量所占的内存区通常比较小。

**参考:**

【1】:《疯狂Java讲义》

【2】:《Java核心技术 卷一》

【3】:

公告:
1. 本站所有资源来源于用户上传和网络,如有侵权请联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系站长处理!
6. 本站不售卖代码,资源标价只是站长收集整理的辛苦费!如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
7. 站长QQ号码 2205675299

资源库 - 资源分享下载网 » Java Review (八、面向对象—-成员变量和局部变量)

常见问题FAQ

关于资源售价和售后服务的说明?
本站所有资源的标价均为本站收集资源的辛苦费,不代表资源本身的价值。软件是高智慧高价值的商品,不可能是白菜价。本站资源标价只是赞助费用,收取的赞助费仅用来维持本站的日常运营!毕竟收集整理资料需要投入云计算资源和站长大量的精力。
代码有没有售后服务和技术支持?
由于代码的运行具有不可预见性,本站不保证代码完整可运行,不提供技术支持和售后服务。 本站原创代码都是站长自己开发的,可以有偿提供技术支持服务。 网站里标明【亲测】的代码都是站长亲测过的,其他的代码由于精力有限,没有一一测试,不能保证代码就一定能够使用,更没有技术支持服务,下载前请自行斟酌。
有没有搭建服务?
由于搭建服务比较费时费力,所以本站除了原创代码外均不提供搭建服务。本站分享代码纯属兴趣爱好,不以盈利为目的,请勿咨询有没有搭建服务,谢谢理解。
链接地址失效了怎么办?
请带上资源链接地址联系客服,工作时间内我们看到后将第一时间回复。
关于解压密码
本站资源一般都没有加密,如果发现需要解压密码的,那么就输入 hao.35dc.com 试试。

发表评论

资源库,由老程序员细心甄别、精心筛选,只为提供优质的源码资源

关于我们 联系我们