定义

编程的本质,就是对内存中数据的访问和修改。变量相当于一个有名称的容器,该容器用于装各种不同类型的数据。
程序所用的数据都会保存在内存中,程序员需要一种机制来访问或修改内存中的数据。这种机制就是变量,每个变量都代表了某一小块内存,而且变量是有名字的,程序对变量赋值,实际上就是把数据装入该变量所代表的内存区域的过程;程序读取变量的值,实际上就是从该变量所代表的内存取值的过程。
Java引用变量有两个类型:编译时类型 和 运行时类型。编译时类型由申明该变量时使用的类型决定;运行时类型由实际赋给该变量的对象决定。
变量 - 图1

成员变量

在类中定义的变量。该变量无须显式初始化,系统会在这个类的准备阶段或创建该类的实例时进行默认初始化,基本类型就初始化为基本类型对应的初始化值,引用类型就初始化为null。成员变量或属于类或属于实例,因此它总是保存在类或实例的堆内存中。

实例变量

作用域与类的实例相同。类实例化后才会分配内存空间,才能访问。

类变量

又称全局级变量或静态变量,需要使用static关键字修饰。类级变量在类定义后就已经存在,占用内存空间,通过类名来访问,不需要实例化。注:十分不建议用实例访问,容易引起混乱

局部变量

指在方法中定义的变量。除形参之外,都必须显式初始化,即,必须先赋值才能使用。因为在定义时系统并未为其分配内存空间,直到初始化后,才会为局部变量分配内存,并将初始值保存到这块内存中。局部变量既不属于类也不属于实例,因此它总是保存在其所在方法的栈内存中。

形参

在方法签名时定义的变量,作用域在整个方法内有效。

方法变量

在方法体内定义的局部变量,作用域从定义该变量的地方生效,到该方法结束时失效。

块变量

在代码块中定义的局部变量,作用域从定义该变量的地方生效,到该代码块结束时失效。

注意

  1. Java允许局部变量和成员变量同名,如果方法里的局部变量和成员变量同名,局部变量会覆盖成员变量,如果需要在这个方法里引用被覆盖的成员变量,则可使用this(对于实例变量)或类名(对于类变量)作为调用者来限定访问成员变量。
  2. 定义变量时,能用局部变量就不用成员变量,能用块变量就不用方法变量。优点有二:减小了变量的生存时间,即减少了内存开销;减小了变量作用域,即提高了程序的内聚性。
  • 代码演示

演示代码1:

  1. {
  2. int age = 23;
  3. String name =“一野";
  4. // 正确,在块内部可以访问 age 和 name 变量
  5. System.out.println( name +"已经"+ age +"岁了");
  6. }
  7. // 错误,在块外部无法访问 age 和 name 变量
  8. System.out.println( name +"已经"+ age +"岁了");

演示代码2:

  1. publicclassDemo{
  2. publicstaticString name ="一野";// 类级变量
  3. publicint i;// 对象实例级变量
  4. // 属性块,在类初始化属性时候运行
  5. {
  6. int j =2;// 块级变量
  7. }
  8. publicvoidtest1(){
  9. int j =3;// 方法级变量
  10. if(j ==3){
  11. int k =5;// 块级变量
  12. }
  13. // 这里不能访问块级变量,块级变量只能在块内部访问
  14. System.out.println("name="+ name +", i="+ i +", j="+ j);
  15. }
  16. publicstaticvoidmain(String[] args){
  17. // 不创建对象,直接通过类名访问类级变量
  18. System.out.println(Demo.name);
  19. // 创建对象并访问它的方法
  20. Demo t =newDemo();
  21. t.test1();
  22. }
  23. }
  24. ========控制台===========
  25. 一野
  26. name=一野,i=0,j=3