Java final关键字

1 final修饰变量

1.1 final概述

        final单词直译为“最终的“,在Java中可以用来修饰变量、方法和类:

  • final修饰的变量:可以初始化,不能再更改
  • final修饰的方法:不能在子类中重写
  • final修饰的类:不能再被继承派生出子类了

1.2 final修饰局部变量

        在方法中声明的变量称为局部变量。

        局部变量加final修饰以后,只能初始化一次,不能再次更改。因此 final 修饰的变量可以在声明的同时初始化或者在构造函数中初始化。

        注意:当引用类型变量被设置为final时候,表示其值就是引用对象的地址值不能再次修改了,但是此时被引用对象的属性或者元素是可以被修改的。

        使用final的目的是保护局部变量的值不变,避免在方法运算期间被意外篡改。如果一个需要反复更改的局部变量就不要使用final修饰。

        查看如下所示代码:

        int 类型的变量a添加了 final 修饰符,则被初始化之后将不能被再次赋值。

        另外, final 修饰的变量 arr 是int类型的数组,也是只能被初始化一次不能再次被修改。但是因为变量 arr 是引用类型,其值是数组对象的首地址(初始化以后不能再次被修改),即变量arr与数组之间的引用关系不能发生改变了;但是数组的内容是可以改变的。因此可以给数组的元素赋值,但是不能给 arr 重新定义。

        编写代码,测试 final 修饰的基本类型变量和引用类型变量。

        案例示意代码如下:

import java.util.Arrays;

public class FinalDemo1 {
    public static void main(String[] args) {
        final int a;
        a = 8; //第一次为变量赋值,称为初始化
        System.out.println(a); //
        //a = 9; //编译错误,a不能再次被修改
        final int b = 9; //声明变量直接初始化
        System.out.println(b);
        //b = 10; //编译错误,不能再次修改final变量

        //final修饰的引用类型变量:
        //引用类型变量初始为一个地址值后不能再次修改
        final int[] arr = {5, 6};//arr中存储的数组地址不能再次修改类
        //arr引用不能修改,但是被引用对象的内容可以修改
        arr[0] = 9;
        System.out.println(Arrays.toString(arr)); //[9, 6]
        //不可以更改arr变量的值,因为arr是final类型的!
        //arr = new int[8];

        final Ball ball = new Ball();
        ball.d = 10;
        System.out.println(ball.d);
        //不能更换ball的值,也就是地址值
        //ball = null;
    }
}

class Ball{
    int d = 5;
}

1.3 final修饰方法的参数

        Java中方法参数也是一种局部变量,只是其声明位置是方法参数,在接收到传递参数的时候初始化。

        在方法参数上可以使用final修饰。final修饰以后也是初始化以后不能再次修改,由于方法参数是在调用方法传递参数值时候初始化的,所以在方法运行期间方法参数变量的值不能修改了。

        使用final修饰方法参数的好处也是保护变量的值,避免在方法运行期间参数变量的值被意外篡改。

        查看如下代码示例:

        方法 test 的第二个参数被声明为 final,在方法内部不能再修改其数值了。

        定义带两个参数的方法(其中一个参数用 final 修饰),编写代码,测试 final 修饰的参数的使用。

        案例示意代码如下:

public class FinalDemo2 {
    public static void main(String[] args) {
        test(5,6);
        test(7,8);
    }
    public static void test(int a, final int b) {
        a = 9;
        //b = 8; //编译错误,不能再次更改变量b
        System.out.println("a:"+a+",b:"+b);
    }
}

1.4 final修饰实例变量

        在类中声明的对象属性,由于是属于每个对象实例的变量所以也称为“实例变量”。

        final可以修饰实例变量,在final修饰实例变量时候必须直接初始化或者在构造器中初始化,并且实例变量也是在初始化以后不能再次改变了。

        使用final修饰实例变量的目的也是保护实例变量,使其值在初始化以后不能改变,避免程序的意外篡改。比如如果希望一个对象的唯一ID编号,在初始化以后不能改了,就可以利用final修饰。

        在实际开发中很少使用final修饰的实例变量!主要原因是不方便对象的复用。很多Java底层框架都会利用对象池重复使用对象,避免反复创建销毁对象的性能开销,如果对象属性是final的,就无法再次进行赋值重用对象了!

        查看如下代码示例:

        类 Eoo 的实例变量 a 和 b,都声明为 final,在 main 方法中测试发现,创建 Eoo 对象后,可以访问该属性,但是不能修改它。

        为类定义 final 修饰的实例变量并编写代码测试其特点。

        案例示意代码如下:

public class FinalDemo3 {
    public static void main(String[] args) {
        Eoo eoo = new Eoo(8);
        System.out.println(eoo.a); //5
        System.out.println(eoo.b); //8
        //不能再次更改final的实例变量
        //eoo.a = 9;
        //eoo.b = 10;
        Eoo e2 = new Eoo(10);
        System.out.println(e2.a);
        System.out.println(e2.b);
    }
}

class Eoo {
    //final的属性必须初始化
    final int a = 5;
    final int b;
    public Eoo(int b) {
        this.b = b;
    }
}

2 final修饰方法

        方法上可以使用final修饰,final的方法在子类中不能被重写修改了。简单理解:final方法不能被重写。final修饰的方法不会影响方法在当前类中的使用,但是如果派生了子类,则在子类中不能重写修改父类中定义的final方法。

        final方法的好处是避免被子类使用重写语法修改方法的功能,保护方法的功能是“最终”版本。如果需要保护方法的功能,避免在子类中重写修改,就可以使用final进行声明。

        但是在实际工程项目中很少使用final方法,原因是很多框架工具都会采用“动态代理”技术代理(重写)对象的功能,实现灵活的软件功能,如果使用final的方法将直接影响这些框架功能!很多些软件开发企业在编程规范中明确规定:不能声明final方法!

        查看如下示例:

        类 Foo 中的方法 test() 添加了 final 修饰符,可以被子类继承但是不能被子类重写。

        为类定义 final 修饰的方法并编写代码测试其特点。

        案例示意代码如下:

public class FinalDemo4 {
    public static void main(String[] args) {
        Foo foo = new Foo();
        foo.test();

        SubFoo sf = new SubFoo();
        sf.test();
    }
}
class Foo{
    public final void test() {
        System.out.println("Foo.test()");
    }
}
class SubFoo extends Foo{
    //public void test() { //编译错误,不能重写Foo中的final方法
    //	System.out.println("SubFoo.test()");
    //}
}

3 final修饰类

        类名也可以使用final修饰,被final修饰的类将不能再派生子类了,也就是终结了类的继承。简单理解:final类不能被继承。

        final类的好处和final方法类似,也是可以避免被继承和重写,避免被子类修改功能。Java的很多核心API,都是final类型,这样就保护了这些非常重要的API功能。这些API包括:String、Math、Integer、Double、Long等。这些API都不能派生子类。

        在开发中也不允许使用final声明类,原因也是因为声明final类以后,造成很多框架无法采用“动态代理”技术代理扩展对象的功能,很多些软件开发企业在编程规范中明确规定:不能声明final类!

        查看如下示例:

        类Goo添加了 final 修饰符,则不能被继承。

        定义 final 修饰的类,并编写代码测试其特点。

        案例示意代码如下:

public class FinalDemo5 {
    public static void main(String[] args) {
        Goo goo = new Goo();
        goo.test();
    }
}
final class Goo{
    public void test() {
        System.out.println("test()");
    }
}
//class SubGoo extends Goo{ //编译错误,不能继承final类
//}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangyan_1010

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值