4.3 成员变量和局部变量

一、定义

成员变量指的是在类里面定义的变量,也就是前面所说的field;局部变量指的是在方法里定义的变量。
Java程序里的变量划分为如图所示:

1.1 成员变量

成员变量可以不用初始化,系统会为它分配默认初始值。初始化规则与数组初始化规则相同。
成员变量分为类变量和实例变量两种,定义成员变量时,有static修饰的是类变量,类变量从该类准备阶段起开始存在,知道系统完全销毁这个类,类的作用域与这个类的生存范围相同;无static修饰的是实例变量,实例变量则从该类的实例被创建起开始存在,直到系统完全销毁这个类,实例变量的作用域与对于实例的生存范围相同。
只要类存在,程序就可以访问类变量,访问类变量的语法格式:

类名.类变量

只要实例存在,程序就可以访问实例变量,访问实例变量的语法格式:

实例.实例变量

注意:类变量也可以用该类的实例来访问,但实质上还是通过该类来访问类变量,语法格式:

实例.类变量

既是说通过一个实例来修改了类变量的值,由于这个类变量并不属于它,而是属于对于的类。因此修改的仍然是类变量,与通过该类来修改类变量完全相同,这也会导致通过其他实例来访问这个类变量也是被修改的值。

class FieldTest 
{
    //定义一个类变量
    public static String name;
    //定义一个实例变量
    public int a;

    public static void main(String[] args) 
    {
        //定义两个FieldTest类的实例
        var p1=new FieldTest();
        var p2=new FieldTest();

        //访问类变量name;:系统分配默认初始值null
        System.out.println(FieldTest.name);
        //下面通过实例方式访问类变量,实质也是通过类来访问
        System.out.println(p1.name);

        //通过实例p1来修改类变量和实例变量
        p1.name="Java";
        p1.a=10;

        //通过实例p1访问类变量和实例变量
        System.out.println(p1.name);
        System.out.println(p1.a);

        //通过实例p2访问类变量和实例变量
        System.out.println(p2.name);//类变量已经被p1进行修改
        System.out.println(p2.a);
    }
}
---------- 运行Java捕获输出窗 ----------
null
null
Java
10
Java
0

输出完成 (耗时 0 秒) - 正常终止

从上面可以发现:类变量的作用域比实例变量的作用域大。实例变量也可以访问类变量,同一个类的所有实例变量访问类变量时,实际上都是访问的该类的同一个变量。在以后的编程中,对于static修饰的类变量,最好用类来访问,增加程序的可读性

1.2 局部变量

与成员变量不同的是,局部变量除形参以外,必须进行显示初始化,也就是说,必须先给方法局部变量和代码块局部变量指定初始值,否则不可以访问它。局部变量分为三种
1、形参:在定义方法签名时定义的变量,形参的作用域在整个方法内有效。
2、方法局部变量:在方法体内定义的局部变量,它的作用域是从定义该变量的地方生效,到该方法结束时失效。
3、代码块内的局部变量:在代码块定义的局部变量,这个局部变量的作用域从定义改变了的地方生效,到代码块结束的地方失效。

{
    public static void main(String[] args) 
    {
        {
            //定义一个代码块局部变量
            int a;
            //下面代码将出现错误,因为变量a还未初始化
            //System.out.println("代码块局部变量a:"+a);
            //BlockTest.java:9: 错误: 可能尚未初始化变量a
            a=5;
            System.out.println("代码块局部变量a:"+a);
        }

        //在代码块外访问变量a是不存在的,超出了代码块局部变量a的作用域
        //System.out.println(a);
        //BlockTest.java:16: 错误: 找不到符号
    }
}
---------- 运行Java捕获输出窗 ----------
代码块局部变量a:5

输出完成 (耗时 0 秒) - 正常终止

Java允许局部变量和成员变量同名,如果方法里的局部变量与成员变量同名,局部变量会覆盖成员变量,如果需要在这个方法里引用被覆盖的长远变量,则可以使用this(对于实例)或类名(对于类变量)作为调用者来访问成员变量。

class  VariableOverrrideTest
{
    //定义一个name实例变量
    private String name="U盘";
    //定义一个price类变量
    public static double price=55.0;

    //定义普通方法
    public void info()
    {
        //方法里的局部变量覆盖成员变量
        var name="孙悟空";
        //直接访问name变量,将输出name的局部值
        System.out.println(name);

        //使用this来输出name实例变量的值
        System.out.println(this.name);
    }
    public static void main(String[] args) 
    {
        //方法里的局部变量会覆盖成员变量
        var price=65.0;
        //直接访问price变量,将输出局部变量的值
        System.out.println(price);
        //使用类名访问局部类变量
        System.out.println(VariableOverrrideTest.price);
        //运行info()
        new VariableOverrrideTest().info();
    }
}
---------- 运行Java捕获输出窗 ----------
65.0
55.0
孙悟空
U盘

输出完成 (耗时 0 秒) - 正常终止

猜你喜欢

转载自www.cnblogs.com/weststar/p/12347859.html