5.3 成员变量和局部变量
在Java语言中,根据定义变量位置的不同,可以将变量分成两大类:成员变量和局部变量。成员变量和局部变量的运行机制存在较大差异。
5.3.1 成员变量和局部变量
成员变量指的是在类范围里定义的变量,也就是介绍的Field;局部变量指的是在方法里定义的变量。成员变量又分为类变量与实例变量。其中使用static修饰的就是类变量,可以通过类直接访问,没有用static修饰的是实例变量。类变量从这个类的准备阶段开始就存在,直到系统完全销毁这个类。实例变量从该类的实例被创建时开始存在,直到系统销毁这个类的实例。
举例1:
package com.langsin.test;
public class Test {
public static String name = "张三"; //类变量
public String age = "25"; //实例变量
public static void main(String[] args) {
Test test = new Test();
test.age = "36";
test.name = "李四";
System.out.println(test.age);
System.out.println(test.name);
Test test1 = new Test();
System.out.println(test1.age);
System.out.println(test1.name);
}
}
注意:实例Field随着实例的存在而存在,而类Field则随着类的存在而存在。实例也可以访问类Field, 同一个类的所有实例访问类Field时 ,实际上访问的是该类本身的同一个Field。
局部变量的分类:
1、 形参:在定义方法名时定义的变量,形参的作用域在整个方法内有效。
2、 方法局部变量:在方法体内定义的局部变量,它的作用域是从定义该变量的地方生效,到该方法结束时失效。
3、 代码块局部变量:由代码块中定义的局部变量,这个局部变量的作用域从定义该变量的地方生效,到该代码块结束时失效。
举例2:
public void getSum(int a,int b){ //a,b为形参局部变量
int num = a+b; // num为方法局部变量
for(int i=0;i<5;i++){ // i 为代码块局部变量,for循环结束时,i失效
num = num + i;
}
System.out.println(i);
System.out.println(num);
}
在Java中,成员变量的作用域是整个类内有效,一个类里不能定义两个同名的成员变量,一个方法里不能定义两个相同的局部变量,但是Java允许局部变量和成员变量同名,如果方法里的局部变量跟成员变量同名,那么在一个方法内使用成员变量时,需要使用this关键字进行区分。因为在方法中使用时,采用的是就近原则。
举例3:
Public class Test {
public String name = "zhangsan";
public void printName(String name){
String result = this.name + name;
System.out.println(result);
}
Public void printName(){
System.out.println(this.name);
}
public static void main(String[] args) {
Test test = new Test();
test.printName("是张三");
test.printName();
}
}
总结一下成员变量与局部变量的区别?
1.类中的位置
成员变量:
都是方法的全局上。与方法是平级的。
局部变量:
方法声明上:形参
方法体内:
代码块内:
2.内存中的位置
成员变量:
类变量:
方法区中的静态区域
实例变量:
堆内在中
局部变量:
栈内存中
3.生命周期
成员变量:
类变量:
从类的准备阶段一直到类的销毁阶段
实例变量:
从对象的准备阶段一直到类的销毁阶段
局部变量:
出了那一对{}就不再被使用
4.初始化值
成员变量:
有初始化值,与变量类型有关。
局部变量:
没有初始化值。
5.3.2 变量的使用规则
在Java中定义变量时,需要根据不同情况来定义变量的范围。
如果变量是用来描述类或者对象的 固有信息 ,比如一些固定不变的值的信息,需要将变量定义成 类变量 。
如果在某个类中需要定义一个变量来保存该类或者实例运行时的状态信息。或者变量需要在整个类范围内有效,则定义成成员变量。
如果只需要在方法中运行,则变量需要定义成局部变量。
在程序中,应该尽可能地缩小局部变量的作用范围,局部变量的作用范围越小,在内存中停留的时间越短,程序运行性能就越好。
举例1:
public class Test {
public static int RUN_SUCCESS = 0;
public static int RUN_FAILURE = 1;
public int runStatus(int a){
if(a>0){
return Test.RUN_SUCCESS;
}else{
return Test.RUN_FAILURE;
}
}
public static void main(String[] args) {
Test test = new Test();
int result = test.runStatus(10);
if(result==Test.RUN_SUCCESS){
System.out.println("程序运行正常");
}else{
System.out.println("程序运行失败");
}
}
}