Java中变量分为两类:成员变量和局部变量
成员变量指的是在类范围里定义的变量,包括实例Field(不以static修饰)和类Field(以static修饰)。局部变量指的是在方法里定义的变量,包括形参、方法局部变量、代码块局部变量。
实例.类Field与类.类Field修改类Field的结果相同,都会导致该类的其他实例来访问这个类Field时也将获得这个被修改过的值。
成员变量无须显示初始化,只要为一个类定义了类Field或实例Field,系统就会在这个类的准备阶段或创建该类的实例时进行默认初始化。同一个类的所有实例访问类Field时,实际上访问的是该类的同一个Field。
class Person
{
//定义一个实例Field
public String name;
//定义一个类Field
public static int eyeNum;
}
public class PersonTest
{
public static void main(String[] args)
{
//Person类已经初始化了,则eyeNum变量起作用了,输出0
System.out.println("Person的eyeNum类Field值:"
+ Person.eyeNum);
//创建Person对象
Person p = new Person();
//通过Person对象的引用p来访问Person对象name实例Field
//并通过实例访问eyeNum类Field
System.out.println("p变量的name Field值是:" + p.name
+ " p对象的eyeNum Field值是:" + p.eyeNum);
//直接为name实例Field赋值
p.name = "孙悟空";
//通过p访问eyeNum类Field,依然是访问Person的eyeNum类Field
p.eyeNum = 2;
//再次通过Person对象来访问name实例Field和eyeNum类Field
System.out.println("p变量的name Field值是:" + p.name
+ " p对象的eyeNum Field值是:" + p.eyeNum);
//前面通过p修改了Person的eyeNum,此处的Person.eyeNum将输出2
System.out.println("Person的eyeNum类Field值:" + Person.eyeNum);
Person p2 = new Person();
//p2访问的eyeNum类Field依然引用Person类的,因此依然输出2
System.out.println("p2对象的eyeNum类Field值:" + p2.eyeNum);
}
}
与成员变量不同的是,局部变量除了形参之外,都必须显示初始化。一个类里不能定义两个同名的成员变量,一个方法里不能定义两个同名的方法局部变量,方法局部变量与形参也不能同名,同一个方法中不同代码块内的代码块局部变量可以同名。如果先定义代码块局部变量,后定义方法局部变量,前面定义的代码块局部变量与后面定义的方法局部变量可以同名。
Java允许局部变量和成员变量同名,如果同名,局部变量会覆盖成员变量,如果需要在这个方法里引用呗覆盖的成员变量,则可以使用this(对于实力Field)或类名(对于类Field)作为调用者来限定访问成员变量。
public class VariableOverrideTest
{
//定义一个name实例Field
private String name = "李刚";
//定义一个price类Field
private static double price = 78.0;
//主方法,程序的入口
public static void main(String[] args)
{
//方法里的局部变量,局部变量覆盖成员变量
int price = 65;
//直接访问price变量,将输出price局部变量的值:65
System.out.println(price);
//使用类名作为price变量的限定,
//将输出price类Field的值:78.0
System.out.println(VariableOverrideTest.price);
//运行info方法
new VariableOverrideTest().info();
}
public void info()
{
//方法里的局部变量,局部变量覆盖成员变量
String name = "孙悟空";
//直接访问name变量,将输出name局部变量的值:"孙悟空"
System.out.println(name);
//使用this来作为name变量的限定,
//将输出price实例Field的值:"李刚"
System.out.println(this.name);
}
}