java 语法 —— final

来源:互联网 发布:淘宝公告栏素材 编辑:程序博客网 时间:2024/06/08 19:49
  • final 成员变量的初始化问题;

1. 实现特别的约束和限制

  • 指向一个 static 型私有成员(仅调用一次),

    public class Coffee {    private static long counter = 0;    private final long id = counter++;    public String toString() {        return getClass().getSimpleName() + " " + id;    }}

2. final 的作用

  • 防止其他人覆盖该方法;
  • 可以有效地关闭动态绑定,或者说告诉编译器不需要对其进行动态绑定;
    • 在 Java 中,除了 static 方法和 final 方法(private 方法属于 final 方法),其他所有的方法都是后期绑定(也叫动态绑定);
    • 绑定的含义即是:将一个方法调用同一个方法主体关联起来;
    • 动态绑定(后期绑定):在运行时根据对象的类型进行绑定;
      • Java 中的多态便是通过动态绑定实现的;

3. public final

public class Pair<K, V> {    public final K key;    public final V val;    public Pair<K, V>(K k, V v) {        key = k; val = v;    }}
  • key 和 value,成员变量都是 public 和 final 的,是为了使 Pair 成为只读的数据传输对象(或信使);

4. 一些细节问题

  • private 方法属于 final 方法,final 方法在编译期即已绑定;

    public class PrivateOverride {    private void f() {        System.out.println("private f()");    }    public static void main(String[] args) {        PrivateOverride p = new Derived();        p.f();    }}class Derived extends PrivateOverride {    public void f() {        System.out.println("public f()");    }}

    期望输出 public f(),但由于 private 方法被自动认为是 final 的,且对导出类是屏蔽的。在此种情况下,Derived 类中的 f() 方法是一个全新的方法。只有非 private 方法才可以被覆盖,但还需要密切注意覆盖 private 方法的现象,这时虽然编译期不会报错,失去了多态机制,也不会按照所期望的来执行。因此,在派生类中,对于基类的 private 方法,最好采用不同的名字。

5. final 修饰对象引用(或数组)

final 修饰对象引用,并非说对象其自身不可被修改,而是对象引用恒定不变,也即一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象(对象本身却是可以被修改的,事实上,Java 并未提供使任何对象恒定不变的途径)。这一限制同样适用于数组,因数组也是对象。

来看 final 修饰这样一个简单的对象引用:

final Test t = new Test();t.setValue(10);         // 修改其内部成员变量的值,是被允许的;t = new Test();         // final 修饰的对象引用,不可以再指向别的对象;

首先来看数组的例子
final 修饰对象引用,或者数组(数组也是一种引用),此对象引用不可以再指向别的对象。

final int[] b = {1,2};b[1]++;             // 允许,b[1] == 3,数组内部的元素可变b = new int[3];         // 不允许,
原创粉丝点击