Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java中final关键字使用指南-Java快速入门教程

Java中final关键字使用指南-Java快速入门教程

作者头像
jack.yang
发布于 2025-04-05 13:08:12
发布于 2025-04-05 13:08:12
7400
代码可运行
举报
运行总次数:0
代码可运行

1. 概述

虽然继承使我们能够重用现有代码,但有时出于各种原因,我们确实需要对可扩展性设置限制;final这个关键字允许我们做到这一点。

在本教程中,我们将了解 final 关键字对类、方法和变量的含义。

2. Final类

标记为final的类无法扩展。如果我们看一下Java核心库的代码,我们会在那里找到许多final类。一个例子是String类。如果我们可以扩展 String 类,重写它的任何方法,并将所有 String 实例替换为特定 String 子类的实例。当我们按以上设想来实现的话,对 String 对象的操作结果将变得不可预测。鉴于 String 类在任何地方都使用,这是不可接受的。这就是 String 类被标记为 final 的原因。 

任何从final类继承的尝试都将导致编译器错误。为了演示这一点,让我们创建final类 Cat

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public final class Cat {

    private int weight;

    // standard getter and setter
}

让我们尝试扩展它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class BlackCat extends Cat {
}

我们将看到编译器错误:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
The type BlackCat cannot subclass the final class Cat

请注意,类声明中的 final 关键字并不意味着此类的对象是不可变的。我们可以自由更改 Cat 对象的字段:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Cat cat = new Cat();
cat.setWeight(1);

assertEquals(1, cat.getWeight());

我们只是无法扩展它。

如果我们严格遵循良好设计的规则,我们应该仔细创建和记录一个类,或者出于安全原因将其声明为final类。但是,在创建final类时,我们应该谨慎行事。

请注意,使类final化意味着没有其他程序员可以改进它。想象一下,我们正在使用一个类,但没有它的源代码,并且其中部分方法存在问题。

如果类是 final,则无法扩展它以重写方法并解决问题。换句话说,我们失去了可扩展性,这是面向对象编程的好处之一。

3. final方法

标记为 final 的方法不能被覆盖。当我们设计一个类并觉得一个方法不应该被重写时,我们可以使这个方法成为final的。我们还可以在 Java 核心库中找到许多final方法。

有时我们不需要完全禁止类扩展,而只需要防止覆盖某些方法。一个很好的例子是 Thread 类。扩展它并因此创建自定义线程类是合法的。但它的isAlive()方法是final的

此方法检查线程是否处于活动状态。由于许多原因,不可能正确覆盖 isAlive() 方法。其中之一是此方法是本地的。本地代码以另一种编程语言实现,通常特定于运行它的操作系统和硬件。

让我们创建一个 Dog 类并使其 sound() 方法final化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Dog {
    public final void sound() {
        // ...
    }
}

现在让我们扩展 Dog 类并尝试覆盖其 sound() 方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class BlackDog extends Dog {
    public void sound() {
    }
}

我们将看到编译器错误:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- overrides
com.baeldung.finalkeyword.Dog.sound
- Cannot override the final method from Dog
sound() method is final and can’t be overridden

如果我们类的某些方法被其他方法调用,我们应该考虑将被调用的方法定为final方法。否则,覆盖它们可能会影响调用方的工作并导致令人惊讶的结果。

如果我们的构造函数调用其他方法,出于上述原因,我们通常应该将这些方法声明为 final

将类的所有方法定final方法和将类本身标记为final方法有什么区别?在第一种情况下,我们可以扩展类并向其添加新方法。

在第二种情况下,我们不能这样做。

4. final变量

标记为 final 的变量无法重新分配。一旦初始化了final变量,就无法更改它。

4.1. final原始变量

让我们声明一个原始的final变量 i,然后给它赋值 1。

让我们尝试为其分配一个值 2:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void whenFinalVariableAssign_thenOnlyOnce() {
    final int i = 1;
    //...
    i=2;
}

编译器说:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
The final local variable i may already have been assigned

4.2. final引用变量

如果我们有一个final的引用变量,我们也不能重新分配它。但这并不意味着它引用的对象是不可变的。我们可以自由更改此对象的属性。

为了证明这一点,让我们声明final的引用变量 cat 并初始化它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final Cat cat = new Cat();

如果我们尝试重新分配它,我们将看到一个编译器错误:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
The final local variable cat cannot be assigned. It must be blank and not using a compound assignment

但是我们可以更改 Cat 实例的属性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cat.setWeight(5);

assertEquals(5, cat.getWeight());

4.3. final字段

final字段可以是常量字段,也可以是一次性写入字段。为了区分它们,我们应该问一个问题——如果我们要序列化对象,我们会包括这个字段吗?如果不是,则它不是对象的一部分,而是一个常量。

请注意,根据命名约定,类常量应为大写,组件由下划线 (“_”) 字符分隔:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static final int MAX_WIDTH = 999;

请注意,必须在构造函数完成之前初始化任何final字段。

对于静态final字段,这意味着我们可以初始化它们:

  • 如上例所示的声明
  • 在静态初始值设定项块中

例如final字段,这意味着我们可以初始化它们:

  • 声明时
  • 在实例初始值设定项块中
  • 在构造函数中

否则,编译器会给我们一个错误。

4.4. final论点

final一个关键字放在方法参数之前也是合法的。final一个参数不能在方法中更改:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void methodWithFinalArguments(final int x) {
    x=1;
}

上述赋值会导致编译器错误:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
The final local variable x cannot be assigned. It must be blank and not using a compound assignment

5. 结论

在本文中,我们了解了 final 关键字对类、方法和变量的含义。虽然我们可能不会在内部代码中经常使用 final 关键字,但它可能是一个很好的设计解决方案

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-04-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【Java学习笔记之二十】final关键字在Java继承中的用法小结
谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字。另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法。 一、final关键字的基本用法 在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。下面就从这三个方面来了解一下final关键字的基本用法。 1、修饰类 当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。fi
Angel_Kitty
2018/04/09
8460
【Java学习笔记之二十】final关键字在Java继承中的用法小结
浅析Java中的final关键字
  谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字。另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法。下面是本文的目录大纲:   一.final关键字的基本用法   二.深入理解final关键字   若有不正之处,请多多谅解并欢迎指正。 一.final关键字的基本用法   在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。下面就从这三个方面来了解一下final关键字的基本用
Spark学习技巧
2018/03/20
1K0
浅析Java中的final关键字
【JAVA】final关键字
在默认情况下,所有的成员变量和成员方法都可以被子类重写。如果父类的成员不希望被子类重写,可以在声明父类成员时使用final关键字修饰。final有“最终”“不可更改”的含义。在Java中,可以使用final关键字修饰类、属性、方法。在使用final关键字时需要注意: (1)使用final关键字修饰的类不能有子类。 (2)使用final关键字修饰的方法不能被子类重写。 (3)使用final关键字的变量是常量,常量不可修改。
颜颜yan_
2022/12/16
5120
【JAVA】final关键字
Java 中的static关键字使用指南-Java快速入门教程
我们将了解如何将 static 关键字应用于变量、方法、块和嵌套类,以及它有什么不同。
jack.yang
2025/04/05
900
Java 中的static关键字使用指南-Java快速入门教程
java关键字_Java关键字
Java keywords are the reserved words that are used by the Java compiler. These keywords have special meaning to the Java compiler. The reserved keywords help us in writing code and help the compiler in understanding the code and create the bytecode.
用户7886150
2020/12/13
1.1K0
final关键字修饰类、变量与方法【总结】
在 Java 编程的世界里,final 关键字就像一把神奇的 “锁”,一旦使用,就能赋予类、变量和方法独特的性质。今天,就让我们一同深入探究 final 关键字修饰类、变量和方法时的各种表现和用途,通过丰富的代码示例,感受它为我们的编程带来的便利与保障。
潜意识Java
2025/01/17
2400
final关键字修饰类、变量与方法【总结】
JAVA面试中的final关键字,你真的了解吗
final关键字的使用方法以及含义,在JAVA面试中经常会被问到,final可以修饰变量,方法和类,用于表示所修饰的内容一旦赋值之后就不会再被改变,比如String类就是一个final类型的类。
程序员小强
2019/09/20
1K0
JAVA面试中的final关键字,你真的了解吗
Java中的final关键字详解
子类可以在父类的基础上改写父类内容,比如,方法重写。那么我们能不能随意的继承API中提供的类,改写其内容呢?显然这是不合适的。为了避免这种随意改写的情况,Java提供了final 关键字,用于修饰不可改变内容。 final: 不可改变。可以用于修饰类、方法和变量。
共饮一杯无
2022/11/28
3370
final关键字
final可以修饰非抽象类、非抽象类成员方法和变量。 (1)final类:不能被继承,没有子类,final类中的方法默认是final的; (2)final方法:不能被子类的方法覆盖,但可以被继承; (3)final成员变量:表示常量,只能被赋值一次,赋值后值不再改变; (4)final不能用于修饰构造方法。 (父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final的) 1.final类 final类不能被继承,因此final类的成员方法没有机会被覆盖,默认是fi
Mister24
2018/05/14
8750
了解final关键字在Java并发编程领域的作用吗?
在Java并发编程领域,final关键字扮演着一个至关重要的角色。虽然很多同学熟悉final用于修饰变量、方法和类的基本用法,但其在并发环境中的应用和原理却常常被忽视。final关键字不仅仅是一个简单的修饰符,它在多线程编程中确保对象状态的可见性和不变性,这对于构建线程安全的应用至关重要。本文将深入探讨final关键字的作用,揭示其在Java并发编程领域中的重要性及实现原理。
阿珍
2024/10/24
1460
了解final关键字在Java并发编程领域的作用吗?
面试官:小伙子来说一说Java中final关键字,以及它和finally、finalize()有什么区别?
面试官:“小伙子,用过final关键字吗?” 我:“必须用过呀” 面试官:“好,那来说一说你对这个关键字的理解吧,再说一说它与finally、finalize()的区别” 我:“好嘞!”
JavaBuild
2024/05/27
1230
面试官:小伙子来说一说Java中final关键字,以及它和finally、finalize()有什么区别?
​JMM中的final关键字解析
与前面介绍的锁和volatile相比较,对final域的读和写更像是普通的变量访问。对于final域,编译器和处理器要遵守两个重排序规则:
Java技术江湖
2019/09/25
6390
JAVA知识基础(五):深入理解final关键字
当final变量修饰基本数据类型以及String类型时,编译期间能知道它的确切值时,编译器会把它当做编译期常量使用。
栗筝i
2022/12/01
2400
Java中的final关键字【详解】
被final关键字修饰的变量是常量,一旦赋值,不可被修改,而且必须在初始化对象的时候赋值;
訾博ZiBo
2025/01/06
920
final关键字你真的会用?
codeReview的时候,看到各种final关键字的”骚“操作,今天认真复习一下final关键字。 我们都知道final关键字可以使用到类上,也可以使用道方法上,也可以使用到数据上,但是他的使用会为我们提供哪些好处呢?
袁新栋-jeff.yuan
2020/08/26
3740
final关键字详解
final修饰的类不能被继承,修饰的方法不能被重写,修饰的变量不能被二次赋值,总之,final就是最终的意思,保证了不变性。除了对不变性的保障,对有序性final也做出了他的贡献。
naget
2019/07/03
5300
Java关键字final、static总结与对比
Java关键字final有“不可改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变:设计或效率。
chenchenchen
2022/03/09
9590
Java关键字final、static总结与对比
深入理解final关键字
通常我们对Java中final关键字的理解是“用final修饰的变量是不可变的”,如果尝试对final变量多次赋值,编译器将报错。似乎final的作用就是保证变量不可变,这没有错,但是如果我们在Java中灵活应用final的被修饰目标不可变的特性,往往能发掘出很多令人意想不到的效果,而非仅仅保证变量不可变这么粗浅而已。下面我们来说说final关键字的多重用法 一 用final修饰普通变量通常分为两种情况,修饰普通基本类变量和修饰引用类型变量,也就是对象类型变量。 修饰普通基本类型变量最能清楚直白的表现出fi
用户1608022
2018/04/11
7290
一文了解 final 关键字的特性、使用方法以及实现原理
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看
Java技术江湖
2019/09/26
1.4K0
一文了解 final 关键字的特性、使用方法以及实现原理
Java 中的同步关键字指南-Java快速入门教程
简而言之,在多线程环境中,当两个或多个线程尝试同时更新可变共享数据时,就会发生争用条件。Java 提供了一种机制,通过同步对共享数据的线程访问来避免竞争条件。
jack.yang
2025/04/05
1330
相关推荐
【Java学习笔记之二十】final关键字在Java继承中的用法小结
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验