Java~深入认识final关键字

目录

final数据

 final方法 

final和private关键字

final类


在Java中,final通常是指“这是无法改变的”,使用final的原因可能是因为:设计和效率。从可能使用到final关键字的三种情况来了解它:数据、方法和类。

final数据

在Java中,编译期常量这类数据必须是基本数据类型,并且以关键字final表示,该类常量在定义时必须对其进行赋值。

一个既是static又是final的域只占据一段不能改变的存储空间。

对于基本数据类型,final使数值恒定不变;而对于对象的引用,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象,然而该对象自身却是可以改变的。

通过下列代码来理解finalstatic final:

import java.util.Random;

public class FinalData {
    private static Random rand = new Random(47);
    private String id;

    public FinalData(String id) {
        this.id = id;
    }
    private final int i = rand.nextInt(20);
    private static final int Value = rand.nextInt(20);

    @Override
    public String toString() {
        return  id + ": " +
                "i= " + i +
                " Value: " + Value;
    }

    public static void main(String[] args) {
        FinalData fd1 = new FinalData("fd1");
        System.out.println(fd1);
        //fd1.i = 5;Error: 当数据定义为final时,不能再对其进行改变
        System.out.println("创建一个新的FinalData对象");
        FinalData fd2 = new FinalData("fd2");
        System.out.println(fd2);
    }
}

运行结果如下: 

在上述代码中,i是用final定义的,Value是用static final定义的,为了更加清晰地理解它们的含义,在初始化时利用了随机生成的方法。通过运行结果,可以看出:

①final使数据成为一个常量,在该对象的引用中不能对其进行改变,但是在创建一个新的对象的值,i会发生改变,说明final只能使定义的变量在该对象的引用中是唯一性的;

②Value不论是在该对象的引用或者是在创建新对象时,都不会发生改变,因为它是static定义的,在装载时已被初始化,而不是在创建新对象时初始化。

final参数

Java允许在参数列表中以声明的方式将参数指明为final。这意味着无法在方法中更改参数引用所指向的对象。

例如:

    public int g(final int i){
        return i + 1;
    }

 final方法 

使用final方法的原因有两个:①把方法锁定,以防止任何继承类修改它的含义;②为了提高效率。

final和private关键字

类中所有的private方法都是隐式地指定为是final的,由于无法用private方法,所以也就无法覆盖它(修改它的含义)。可以对private方式使用final修饰,但这不会给该方法增加任何的额外含义。

通过下列代码来理解final方法:

 

class WithFinal{
    private final void f(){
        System.out.println("WithFinal.f()");
    }
    private void g(){
        System.out.println("WithFinal.g()");
    }
}
class FinalInit extends WithFinal {
    private final void f(){
        System.out.println("FinalInit.f()");
    }
    private void g(){
        System.out.println("FinalInit.g()");
    }
}
class FinalInit1 extends FinalInit{
    public final void f(){
        System.out.println("FinalInit.f()");
    }
    public void g(){
        System.out.println("FinalInit.g()");
    }
}
public class Final extends FinalInit{
    public static void main(String[] args) {
        FinalInit1 op1 = new FinalInit1();
        op1.f();
        op1.g();
        //可以发生向上转型
        FinalInit op = op1;
        //但不能调用FinalInit的方法
        //op.g(); Error: FinalInit中的方法是以private修饰的
        //op.f(); Error: FinalInit中的方法是以private修饰的
        WithFinal wp = new WithFinal();
        //wp.g(); Error: WithFinal中的方法是以private修饰的
        //wp.f(); Error: WithFinal中的方法是以private修饰的
    }
}

通过上述代码可以看出,当方法以private定义时,它就不是基类的接口的一部分,它仅是一些隐藏于类中的代码,只不过具有相同的名称。但如果在导出类中以相同的名称生成一个public、protected或包访问权限的方法,该方法就不会产生在基类中出现的“仅具有相同名称”的情况。此时并没有覆盖该方法,只是生成了一个具有相同名字的新方法。

由于private方法无法触及而且能够有效隐藏,所以我们不需要过多的考虑它,只把它看做是因为它所归属的类的组织结构的原因而存在。

final类

当某个类的整体定义为final时,就表明了该类永远无法被继承。

定义方式:

final class Test{
    int i = 7;
    int j = 1;
}

在写代码的过程中,可以根据自己的意愿来选择是否要将该类定义为final类。由于final类禁止继承,所以final类中的所有方法都隐式的定义为final的,因为无法覆盖它们。在final类中可以给方法添加final修饰词,但这没有任何意义。

 

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Li_yizYa

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

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

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

打赏作者

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

抵扣说明:

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

余额充值