6.4 成员变量与局部变量

最后更新于:2022-04-01 14:11:01

前面我们学习了类的定义,我们不难理解,定义类其实就是在定义类中的成员. 成员包括成员变量和成员函数. 说到成员变量,我们很自然会想到前面提到过的局部变量,那么它们之间有什么区别呢? 首先我们定义一个People类: ~~~ class People//定义一个People类 { String name;//姓名属性 int age;//年龄属性 char sex; void run()//跑的方法 { System.out.println(name+"开始跑步了."); } void information() { System.out.println("姓名:"+name+";\n性别:"+sex+";\n年龄:"+age+"."); } } ~~~ 然后我们从四个方面来分析下这两种变量的区别. **1.从它们的定义环境来分析**,我们看一段代码. ~~~ class PeopleTest { public static void main(String[] args) { People kobe = new People();//创建一个People的对象kobe String name = "jordan"; int age = 49; char sex = '男'; kobe.name = "KOBE"; kobe.age = 37; kobe.sex = '男'; kobe.information(); kobe.run(); } } ~~~ 我们可以看到People类中我们定义了name,age,sex这三个变量就是成员变量;而在main方法中我们定义了kobe,name,age,sex这四个变量都是局部变量,那么很明显就看出了它们的不同之处: 成员变量定义在类中,整个类中都可以访问. 局部变量定义在函数,语句,局部代码块中,只在所属区域有效. **2,从它们在内在中存放形式来分析**: 联系上一节以及4.3节的函数的内存分配两节我们很自然知道这两种变量的区别在于: 成员变量存在于堆内存的对象中. 局部变量存在于栈内存的方法中. **3,从它们的默认初始化来分析**,我们运行上面的代码: ~~~ class PeopleTest { public static void main(String[] args) { People kobe = new People();//创建一个People的对象kobe String name = "jordan"; int age = 49; char sex = '男'; kobe.name = "KOBE"; kobe.age = 37; kobe.sex = '男'; kobe.information(); kobe.run(); System.out.println("name:"+name+";\nsex:"+sex+";\nage:"+age+"."); } } ~~~ 结果如下: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-18_573c41ae91812.jpg) 我们再把该代码稍做修改: ~~~ class PeopleTest { public static void main(String[] args) { People kobe = new People();//创建一个People的对象kobe String name; int age; char sex; kobe.name = "KOBE"; kobe.age = 37; kobe.sex = '男'; kobe.information(); kobe.run(); System.out.println("name:"+name+";\nsex:"+sex+";\nage:"+age+"."); } } ~~~ 结果: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-18_573c41aeb3a06.jpg) 我们看出一个很显然的区别就是: 成员变量都有默认初始化值. 局部变量没有默认初始化值. 所以我们在定义成员变量时,如果我们需要特定的初始值,我们就一定要显性初始化具体值.对于局部变量,如果我们不初始化,当操作该变量时编译会提示未初始化的错误. **4.从它们的生命周期来分析**,我们再对上面的代码进行一下改动: ~~~ class PeopleTest { public static void main(String[] args) { People kobe = new People();//创建一个People的对象kobe String name = "jordan"; { int age = 49; char sex = '男'; System.out.println("name:"+name+";\nsex:"+sex+";\nage:"+age+".");//可以打印出三个局部变量的值 } kobe.name = "KOBE"; kobe.age = 37; kobe.sex = '男'; kobe.information(); kobe.run(); System.out.println("name:"+name+";\nsex:"+sex+";\nage:"+age+".");//报错,找不到sex和age这两个变量 } } ~~~ 结果: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-18_573c41aec81d0.jpg) 而当我们把最后一句打印语句注释之后的结果: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-18_573c41aeda80a.jpg) 我们可以看到: 成员变量随着对象的创建而存在,随着对象的消失而消失. 局部变量随着所属区域的执行而存在,随着所属区域的结束而释放. 最后,我们再来看一个比较需要注意的地方,那就是成员变量和局部变量的同名情况. 我们把People类修改一下: ~~~ class People//定义一个People类 { String name;//姓名属性 int age;//年龄属性 char sex; void run()//跑的方法 { System.out.println(name+"开始跑步了."); } void information() { String name = "JAMES"; int age = 29; char sex = '女'; System.out.println("姓名:"+name+";\n性别:"+sex+";\n年龄:"+age+"."); } } ~~~ 结果: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-05-18_573c41aeedc9c.jpg) 我们看到在打印出了局部变量的值,这是由于局部变量在栈的方法中,程序会把值直接赋值给局部变量,如果当在栈中找不到,则到堆内存中寻找指定的成员变量.这一点在以后的操作中一定要小心. 成员变量都有默认初始化值. 局部变量没有默认初始化值.
';