Java - [面向对象]final

2020/01/05

2020_0306补充理解

首先,final关键字用于修饰什么?

一共三种:变量方法

final修饰的类不可以有子类。

final修饰的方法不可以被重写。

下面主要说下final修饰的变量:

final成员变量

成员变量是随类初始化对象初始化而初始化的。

  • 类成员变量

必须在声明该类成员变量静态初始化代码块中指定初始值,并且只能二者选其一

public class FinalVariableTest {
    // Method1: Specifying initial value when declaring variables. 
    private static final int count = 10;

    // Method2: Using static block.
    // static {
    //     count = 10;
    // }

}
  • 实例成员变量

必须在声明该实例成员变量构造器非静态初始化代码块中指定初始值,并且只能三者选其一

public class FinalVariableTest {
    // Method1: Specifying initial value when declaring variables.
    private final int age = 24;

    // Method2: Using constructor.
    // public FinalVariableTest(int age){
    //     this.age = age;
    // }

    // Method3: Using statement block.
    // {
    //     age = 20;
    // }
}

final局部变量

final修饰的局部变量在定义时未指定默认值,则可以在后面代码中对该final变量赋初始值,但只能一次,不能重复赋值。

final int a = 1;
final int b;

// Cannot assign a value to final variable a.
// a = 2;
b = 2;

再来看个有意思的地方:

public void test(final int a){
    a = 10;
}

想一下,以上方法是否可以编译通过?

不能的原因是什么?

因为当test()方法被调用时,形参a会根据传入的实参进行初始化,所以被final修饰的变量a,无法进行第二次赋值a = 10;

final修饰基本类型变量与引用类型变量的区别

使用final修饰基本类型变量时,不能对其重复赋值,但对于引用类型变量而言,它保存的仅仅是一个引用,final只能保证该引用变量的引用地址不会发生改变,但这个对象的内部完全可以改变。

@Test
public void referenceFinalTest(){

    final String[] names = new String[10];
    // The reference of names is [Ljava.lang.String;@11bb3ab
    System.out.println("The reference of names is " + names);

    names[0] = "frankie";
    // The reference of names is [Ljava.lang.String;@11bb3ab
    System.out.println("The reference of names is " + names);

    // 0th element in the names is frankie
    System.out.println("0th element in the names is " + names[0]);
}

Reference

  • 《疯狂Java讲义 - 6.4》 - final修饰符


一位喜欢提问、尝试的程序员

(转载本站文章请注明作者和出处 姚屹晨-yaoyichen

Post Directory