【重修Java】《Java编程思想》读书笔记——final关键字

本文是《Java编程思想》的读书笔记,主要探讨了final关键字在Java中的应用,包括final数据、final方法和final类的特性。final数据一旦初始化便不可更改,它可以用来创建常量或确保引用不改变。空白final提供了一种在构造方法中初始化的灵活性。final方法不能被子类重写,而final类则不能被继承,保证了类的封闭性。
摘要由CSDN通过智能技术生成

final关键字

“这是无法改变的。”

final数据

被final修饰的数据一旦被初始化后就不得被改变。基本类型运用final时,数值恒定不变。对象/数组(数组是一种特殊的引用)运用final时,引用恒定不变,可以改变对象的值

引用存在堆栈中,对象存在堆中。final修饰的是堆栈中的对象的引用,而不是堆中的对象。final修饰的引用无法指向堆中另外一个地址的对象,但是可有修改原对象的值,因为引用不会变化。


import java.util.Arrays;

class Value{
    int v;

    public Value(int v) {
        super();
        this.v = v;
    }

    @Override
    public String toString() {
        return "Value [v=" + v + "]";
    }

}

public class FinalData {
    private int id;

    private final char finalValue='f';

    private static final int FINAL_AND_STATIC_VALUE=20;

    private final Value finalObject=new Value(30);

    private final int[] finalArray={1,2,3,4,5};

    public FinalData(int id) {
        super();
        this.id = id;
    }

    void functionWithFinalArgs(final Value value,final int i){
        //final基本类型参数无法修改值,对象参数无法修改引用
//      value=new Value(0);
//      i=0;
    }


    public static void main(String[] args){
        FinalData finalData=new FinalData(1);

        //final基本类型数值无法更改,编译器报错
//      finalData.FINAL_AND_STATIC_VALUE=30;
//      finalData.finalValue='a';

        //final对象/数组 引用无法更改,编译器报错
        Value newValue=new Value(10);
//      finalData.finalObject=newValue;
        int[] newArray={1,2,3};
//      finalData.finalArray=newArray;

        //final对象/数组 对象值可以修改
        finalData.finalObject.v=10;
        System.out.println(finalData.finalObject);

        for(int i=0;i<finalData.finalArray.length;i++){
            finalData.finalArray[i]++;
        }
        System.out.println(Arrays.toString(finalData.finalArray));
    }

}
/*Output:
Value [v=10]
[2, 3, 4, 5, 6]
*/

空白final

被声明final但未给定初值的域。需要在使用之前进行初始化,一般在构造方法中进行初始化。

public class BlankFinalData {

    private final int value;

    // {
    // value=10;
    // }

    public BlankFinalData(int value) {
        super();
        this.value = value;
    }

    public BlankFinalData() {
        super();
        this.value=0;
    }

    public static void main(String[] args){
        BlankFinalData blankFinalData = new BlankFinalData();
        System.out.println(blankFinalData.value);
        blankFinalData=new BlankFinalData(1);
        System.out.println(blankFinalData.value);
    }

}
/*
 * Output
 * 0
 * 1
 */

可以看到注释掉了构造代码块,构造代码块与构造函数不能同时对final参数修改。因为构造代码块优先于构造函数执行,构造代码块执行时参数已经被初始化,构造函数中就不能再次修改。
空白final为final数据提供了更大的灵活性,该类的不同对象final数据的值可能调用不同构造方法而拥有不同值,但值都不能被再次改变。

final数据恒定不变有两个用途:
1.一个永不改变的编译常量(在声明是就初始化)
2.一个在运行时被初始化的值,而你不希望它被改变(空白final)

final方法

final方法不可以被子类重写。

package final_modifier;

public class FinalMethod {

    final void finalMethod(){

    }

    private void privateMethod(){
        System.out.println("father method");
    }

}

class ChildClass extends FinalMethod{
    //final方法不能被重写
//  @Override
//  void finalMethod(){
//      System.out.println("change something");
//  }

    //private方法无法重写
//  @Override
    private void privateMethod(){
        System.out.println("child method");
    }

}

private方法与final方法
private方法与final方法都不能被重写。
更确切的说private方法其实跟子类一点关系没有,private只属于父类,不会被继承。
上例中试图为子类的与父类相同的private方法加上override注解时编译器就会报错,因为并没有方法被重写。

final类

final类不可以被继承。被final修饰的类不能被abstract修饰,final类不能被继承,abstract类需要被继承实现。

欢迎批评指正^ ^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值