Java中的变量只有两种:成员变量和局部变量。
和C++不同,没有全局变量了。
成员变量,field,我习惯称之为**”属性“**(但这些年,因为attribute更适合被叫做属性,所以渐渐不这么叫了)。
局部变量是在方法中定义的变量。
成员变量
和成员方法类似,成员变量也有两种:
- static修饰的变量,也就是类成员变量;
- 没有static修饰的变量,也就是对象变量(也叫实例变量,早期习惯把对象叫做实例,对象初始化叫实例化)。
和成员方法也是类似的:
- 类成员变量由
类.类变量
访问; - 实例变量由
实例.实例变量
访问; - 也可以由实例来访问类变量,
实例.类变量
,但要注意这时实际上访问的是类变量,对其修改会影响其他实例访问。
class Person
{
public String name;
public static int eyeNum;
}
public class PersonTest
{
public static void main(String[] args)
{
System.out.println(Person.eyeNum); // 第一次调用Person类,该类自动初始化,eyeNum默认值是0
// 实例化一个Person
var p = new Person();
// 通过引用变量p来访问这个实例
System.out.println(p.name, p.eyeNum); // p.name默认值是null
}
}
成员变量不需要显式初始化,系统会默认在类的准备阶段或者在实例化的时候进行默认初始化。默认初始化规则和动态初始化数组元素是一样的。
局部变量
局部变量有三种定义形式(在三个不同的地方被定义):
- 形参:定义方法签名时定义的变量,作用域是整个方法的生命期;
- 方法局部变量:方法体内部,作用域是从定义的地方生效,方法结束时失效;
- 代码块局部变量:在代码块内部定义的局部变量,作用域从定义该变量的地方生效,到该代码块结束时失效。
局部变量除形参外,必须显式初始化,否则不能访问。
作用域
- 一个类中不能定义两个同名的成员变量,即便修饰符不同也不行;
- Java允许局部变量和成员变量同名。且方法中的局部变量会覆盖成员变量。如果需要调用被覆盖的成员变量,需使用
this
指针(实例变量)或类名.类变量
(类变量)
道理是这么个道理,但是真正编程的时候还是别这样了,徒增烦恼。
public class VariableOverrideTest
{
private String name = "王五";
private static double price = 78.0;
public static void main(String[] args)
{
var price = 65; // 方法中的局部变量覆盖成员变量
System.out.println(price); // 65
System.out.println(VariableOverrideTest.price); // 78.0
}
public void info()
{
var name = "孙悟空"; // 局部变量覆盖成员变量
System.out.println(name); // 孙悟空
System.out.println(this.name); // 王五
}
}