write:2022-4-28
前文我们学习了Java的数据类型:Java之数据类型,本文我们学习变量的作用域和初始化,文中有大量使用实例讲解分析,需耐心解读代码


文章目录

  • 1. 变量和参数的概念
  • 2. 变量的作用域
  • 3. 参数传递
  • 4. 变量的默认值
  • 5. 变量的初始化
  • 6. 静态变量和实例变量
  • 7. 变量的生命周期
  • 8. 小结
  • 9. 练习题


1. 变量和参数的概念

仔细分析一下代码:

public class Cat{
  private String **name**;      //name:属性
  
  public Cat(String **name**){       //name:方法的参数
    this.name=name;
  }

  public void speak(){
    System.out.println(name+":喵喵喵");
  }

  public static void main(String args[]){
    Cat cat=new Cat("朵拉");
    cat.speak(); 
  }
}

可以发现在不同的地方,变量name代表的含义不同,有不同的作用。

2. 变量的作用域

成员变量:在类中定义,它的作用域是整个类。
局部变量:在一个方法的内部定义,它的作用域是整个方法。
方法参数:方法的参数,它的作用域是整个方法。

eg:

public class Scope{
  int x; //成员变量,作用域是整个类
  
  Scope(int x){
    this.x=x;   //此方法与类同名,this.x(成员变量x)=x(方法参数x),用this关键字就是引用与方法参数同名成员变量
    int y=2;  //局部变量,作用域是这个方法
}

 public void test(){
    x=1;
    y=1;   //编译出错
}
   
  public static void main(String args[]){
    Scope s=new Scope(1);
    System.out.println(s.x);
    System.out.println(s.y);  //编译出错
  }
}

进一步理解this关键字:
eg:

public class Count{
  int data;   //没有显示初始化,默认值为0
  
  public void increase(int data){
    this.data=this.data+data;    //把成员变量data和方法参数data相加再赋值给成员变量data
  }
  
  public static void main(String args[]){
     Count  c1=new Count();
     Count  c2=new Count();
     c1.increase(2);    //0+2=2
     c2.increase(1);    //0+1=1
     System.out.println(c1.data+","+c2.data);  //打印:2,1
  }
}

图解:

java中全局变量的生命周期 java全局变量初始化_开发语言

3. 参数传递

如果参数是基本数据类型,参数传递是将数值传递给方法。
如果参数是对象或数组的引用类型,参数传递是将对象或数组的引用传递给方法。

eg:

public void methodA(){
  int a=1;
  String s=“Hello”
  methodB(a,s);    //调用methodB方法
}

public void methodB(int p1,String p2){
  …
}

试一试
想一想打印输出什么结果

public class ParaTest{
    public int v=0;
    public static void main(String args[]){
	//声明3个局部变量
	int p1=0; // p1是基本数据类型
	ParaTest p2=new ParaTest(); //p2 是对象引用类型
	ParaTest p3=new ParaTest();//p3 是对象引用类型
	//将3个局部变量作为参数传递给changeParameter ()方法
        changeParameter (p1, p2, p3);					
        //打印3个局部变量
        System.out.println("p1= " +p1);
        System.out.println("p2.v= " + p2.v);
        System.out.println("p3.v= " + p3.v);
    }
    public static void changeParameter (int p1, ParaTest  p2, ParaTest  p3) {
	   p1=1; 
	   p2.v=1; 
	   p3=new ParaTest();  
        p3.v=1; 
    }
}

答案:
P1=0
P2.v=1
P3.v=0

分析:

java中全局变量的生命周期 java全局变量初始化_java_02

4. 变量的默认值

在创建一个对象时,JVM会自动为它的成员变量初始化为默认值。
数值型变量的默认值(0)
字符型的默认值(‘\u0000’)
布尔型的默认值(false)
引用类型的默认值(null)。

eg:

public class Sample{
   int v1;
   boolean v2;
   Sample v3;
   public static void main(String args[]){
     Sample sam=new Sample();
     System.out.println(sam.v1);  
     System.out.println(sam.v2);
     System.out.println(sam.v3);
  }
}

打印结果
0
false
null

5. 变量的初始化

1)成员变量会自动初始化:如果编写者显示初始化,那么成员变量的值就是赋值的值,如果没有显示初始化,则默认初始化,成员变量的值就是默认值
2)局部变量必须显式初始化再使用

eg:

java中全局变量的生命周期 java全局变量初始化_java_03

6. 静态变量和实例变量

成员变量分为两种:静态变量和实例变量。
静态变量用static修饰,也叫做类变量。

eg:

public class Sample{
   static int v1;  //静态变量
   int  v2;  //实例变量
   public static void main(String args[]){
      v1=1;
      v2=1;   //编译出错,在静态方法中不能直接访问v2
      Sample s1=new Sample();
      s1.v1=2;
      s1.v2=2;
      Sample.v1=3;
      Sample.v2=3;  //编译出错,不能通过类名访问v2
  }
}

静态变量和实例变量的区别
静态变量在内存中只有一个备份,在JVM加载类时分配内存
实例变量属于特定的实例。每创建一个实例,就会为实例变量分配内存。

eg:

public class Sample{
   static int v1;  //静
   public static void main(String args[]){
      Sample s1=new Sample();
      Sample s2=new Sample();
      s1.v2=1;   
      s2.v2=2;
      s1.v1=3;
      s2.v1=4;
      System.out.println(s1.v2+“,”+s2.v2+“,”+v1); //打印1,2,4
  }
}

java中全局变量的生命周期 java全局变量初始化_java_04

7. 变量的生命周期

方法的参数和局部变量只有当方法被调用时才存在
实例变量的生命周期依附于实例变量
静态变量的生命周期依附于类的生命周期

eg:用唱戏表示

java中全局变量的生命周期 java全局变量初始化_System_05


变量的生命周期

eg:

java中全局变量的生命周期 java全局变量初始化_System_06

8. 小结

java中全局变量的生命周期 java全局变量初始化_java中全局变量的生命周期_07

9. 练习题

1.编译以下代码会出现什么情况?
 public int test(){
 int x;
 int y=x+1;
 return y;
 }

编译出错,提示变量x必须先初始化才能被使用。

2.编译或运行以下代码会出现什么情况?

public class Sample{
 static String v1;
 static boolean v2;
 public static void main(String args[]){
 System.out.println(Sample.v1);
 System.out.println(v2);
 }
 }


编译和运行通过,打印null和false。

3.编译或运行以下代码会出现什么情况?

public class Sample{
 public int method1(){
 int x=0;
 return x+10;
 }public void method2(){
 System.out.println(x);
 }
 }


编译出错,提示method2()方法中的x没有定义。

4.补充setData()方法的代码,把参数data的值赋给实例变量data?

public class Sample{
 int data;
 public void setData(int data){
 //把参数data的值赋值给实例变量data
 …
 }
 }

a) Sample.data=data; b) new Sample().data=data;
c) this.data=data; d) int data=data;
答案:c

5.运行以下Sample类,会得到什么打印结果?

java中全局变量的生命周期 java全局变量初始化_java中全局变量的生命周期_08


a) 打印1,2,1 b)打印1,1,2

c)打印1,1,1 d)打印2,2,1

答案:b