27、详解 Java 中的 final 关键字

简介: 27、详解 Java 中的 final 关键字


一、final 关键字(官方教程)

(1) final 方法

✏️ You can declare some or all of a class’s methods final. You use the final keyword in a method declaration to indicate that the method cannot be overridden(重写) by subclasses. The Object class does this—a number of its methods are final.

📜 你可以把一个类的部分或全部方法声明为是final方法。使用final关键字声明一个方法表示这个方法不能够被子类重写。Object 基类就是这样做的,Object 类的某些方法就是final方法


✏️ You might wish to make a method final if it has an implementation that should not be changed and it is critical to the consistent state of the object.

📜 你可能想要把某个方法声明为final方法,因为该方法的实现是不应该被修改的。你可能想要把某个方法声明为final方法,因为该方法所在的类的对象的一致状态至关重要。


✏️ Methods called from constructors should generally be declared final. If a constructor calls a non-final method, a subclass may redefine that method with surprising or undesirable results.

📜 需要在构造方法中调用的方法通常应该被声明为final,若构造方法调用了非 final 的方法,哪子类就有可能会重写该非 final 方法(此操作导致的后果是令人惊讶和不希望的)


(2) final 类

✏️ You can also declare an entire class final. A class that is declared final cannot be subclassed. This is particularly useful, for example, when creating an immutable class like the String class.

📜 你同样可以把一整个类声明为final,被声明为final的类不能被继承(绝育了😊)

📜 Java 中的 String 类就是一个被final修饰的类,被final修饰的类是不可变的(immutable)

(3) 常量(final 属性)

✏️ The static modifier, in combination with the final modifier, is also used to define constants. The final modifier indicates that the value of this field cannot change.

📜 static 关键字和 final 关键字共同使用可以用来声明常量(被 staticfinal 共同修饰的成员变量是常量)

📜 final修饰符表示:属性的值不能被改变

static final double PI = 3.141592653589793;

✒️ 上面代码中的 PI 就是一个常量

✒️被static修饰表示它在 JVM 中只有一份内存【类变量在程序运行过程中只占用一份固定的内存(存储在方法区)】

✒️ 被final修饰表示它的值是不能被修改的


✏️ Constants defined in this way cannot be reassigned, and it is a compile-time error if your program tries to do so. By convention, the names of constant values are spelled in uppercase letters. If the name is composed of more than one word, the words are separated by an underscore_

📜 被final关键字修饰的常量不能被重新赋值,如果你偏要这样干的话,编译器会给你一个编译时错误。

📜 按照惯例,常量名通常是大写字母,若常量名由多个单词组成:多个单词之间用【下划线分隔】

public static final String BASE_URL = "https://iloveyou.com";

(4) 编译时常量(☆)

✏️ If a primitive type or a string(字符串) is defined as a constant and the value is known at compile time, the compiler replaces the constant name everywhere in the code with its value. This is called a compile-time constant.

📜 如果一个基本数据类型或字符串被声明为常量,并且该常量的值在编译的时候就知道值的话:编译器会用该常量的值替换代码中各个地方的该常量名【类似 C 语言中的宏替换】

✏️ If the value of the constant in the outside world changes (for example, if it is legislated that pi actually should be 3.975), you will need to recompile any classes that use this constant to get the current value.

📜 如果外界的常量的值发生变化(例如:如果立法规定 π 实际上应该是 3.975),您将需要重新编译任何使用该常量的类来获取当前值。

二、final 可被使用在…

📗 若不希望类被继承,可用 final 修改该类

📗 若不希望父类的某个方法被子类重写,可用 final 修饰该方法

📗 若不希望属性的值被修改,可用 final 修饰该属性

📗 若不希望局部变量的值被修改,可用 final 修饰该局部变量

三、细节

(1) 定义之后必须有值

📋 被final修饰的属性定义之后就必须确定(没有默认值)

📋 可以定义候给予初始值

📋 可以在初始化块中给予初始值

📋 可以在构造器中给予初始值

public class FinalKeyword {
  // 没有被 final 修饰的属性定义之后不必须给值(有默认值)
    public String baseURL;
    // 定义时赋值
    // public final String BASE_NETWORK_URL = "";
    public final String BASE_NETWORK_URL; /* ERROR */
    public FinalKeyword() { // 构造器中赋值
        // BASE_NETWORK_URL = "";
    }
    { // 初始化块中赋值
        // BASE_NETWORK_URL = "";
    }
}

(2) static final 赋值

📋 如果被final修饰的属性是静态的,则初始化的位置只能是:① 定义的时候;② 在静态初始化块中

✒️ 不能在构造器中给常量static final)赋值

✒️ 常量必有 static

✒️ 构造器与对象实例挂钩

✒️ static 与对象实例毫无关系

public class FinalKeyword {
    // public static final String BASE_URL = ""; // Right
    public static final String BASE_URL;
    static {
        BASE_URL = ""; // Right
    }
}

(3) final 方法不能被重写,但可被继承使用

📋 final 类只是不能被继承,是可以实例化的

📋 ① 不是 final 类;② 有一个 final 的方法;③ 该 final 方法不能被重写(但是可以被继承)【final 方法不能被子类重写,但可以被子类使用】 能用不可改

public class Whatever {
    public final void test() {
        System.out.println("Whatever: final void test()");
    }
    public static void main(String[] args) {
        // Whatever: final void test()
        new Son().sonTest();
    }
}
class Son extends Whatever {
    public void sonTest() {
        // 使用父类的 final 方法
        super.test();
    }
}

(4) 无需在 final 类中定义 final 方法

📖 若一个类已经是 final 了,则该类中的方法无需定义为 final 方法

public final class Whatever {
    public void test() {
        System.out.println("final 类中定义的方法无需手动加上 final 关键字");
        System.out.println("final 类都不能被继承, 咋可能重写里面的方法嘛!");
    }
}

📖 final 不能修饰构造方法

📖 static final 搭配使用,效果更佳

📖 包装类(Integer、Double、Float、Boolean)都是 final

📖 String 也是 final

四、Exercise

public final class Whatever {
    public int test(final int x) {
        // 被 final 修饰的局部变量 x 不能被第二次赋值赋值
        // ++x; // ERROR
        return x + 1;
    }
}

结束!如有错误,请不吝赐教

相关文章
|
4月前
|
存储 缓存 安全
除了变量,final还能修饰哪些Java元素
在Java中,final关键字不仅可以修饰变量,还可以用于修饰类、方法和参数。修饰类时,该类不能被继承;修饰方法时,方法不能被重写;修饰参数时,参数在方法体内不能被修改。
52 3
|
18天前
|
缓存 安全 Java
Volatile关键字与Java原子性的迷宫之旅
通过合理使用 `volatile`和原子操作,可以在提升程序性能的同时,确保程序的正确性和线程安全性。希望本文能帮助您更好地理解和应用这些并发编程中的关键概念。
40 21
|
8天前
|
Java C语言
课时8:Java程序基本概念(标识符与关键字)
课时8介绍Java程序中的标识符与关键字。标识符由字母、数字、下划线和美元符号组成,不能以数字开头且不能使用Java保留字。建议使用有意义的命名,如student_name、age。关键字是特殊标记,如蓝色字体所示。未使用的关键字有goto、const;特殊单词null、true、false不算关键字。JDK1.4后新增assert,JDK1.5后新增enum。
|
2月前
|
Java 编译器 开发者
Java中的this关键字详解:深入理解与应用
本文深入解析了Java中`this`关键字的多种用法
210 9
|
3月前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
2月前
|
JSON Java 数据挖掘
利用 Java 代码获取淘宝关键字 API 接口
在数字化商业时代,精准把握市场动态与消费者需求是企业成功的关键。淘宝作为中国最大的电商平台之一,其海量数据中蕴含丰富的商业洞察。本文介绍如何通过Java代码高效、合规地获取淘宝关键字API接口数据,帮助商家优化产品布局、制定营销策略。主要内容包括: 1. **淘宝关键字API的价值**:洞察用户需求、优化产品标题与详情、制定营销策略。 2. **获取API接口的步骤**:注册账号、申请权限、搭建Java开发环境、编写调用代码、解析响应数据。 3. **注意事项**:遵守法律法规与平台规则,处理API调用限制。 通过这些步骤,商家可以在激烈的市场竞争中脱颖而出。
|
3月前
|
缓存 安全 Java
Java volatile关键字:你真的懂了吗?
`volatile` 是 Java 中的轻量级同步机制,主要用于保证多线程环境下共享变量的可见性和防止指令重排。它确保一个线程对 `volatile` 变量的修改能立即被其他线程看到,但不能保证原子性。典型应用场景包括状态标记、双重检查锁定和安全发布对象等。`volatile` 适用于布尔型、字节型等简单类型及引用类型,不适用于 `long` 和 `double` 类型。与 `synchronized` 不同,`volatile` 不提供互斥性,因此在需要互斥的场景下不能替代 `synchronized`。
2412 3
|
4月前
|
JavaScript 前端开发 Java
java中的this关键字
欢迎来到我的博客,我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。自学前端2年半,正向全栈进发。若我的文章对你有帮助,欢迎关注,持续更新中!🎉🎉🎉
84 9
|
4月前
|
设计模式 JavaScript 前端开发
java中的static关键字
欢迎来到瑞雨溪的博客,博主是一名热爱JavaScript和Vue的大一学生,致力于全栈开发。如果你从我的文章中受益,欢迎关注我,将持续分享更多优质内容。你的支持是我前进的动力!🎉🎉🎉
75 8
|
4月前
|
Java
final 在 java 中有什么作用
在 Java 中,`final` 关键字用于限制变量、方法和类的修改或继承。对变量使用 `final` 可使其成为常量;对方法使用 `final` 禁止其被重写;对类使用 `final` 禁止其被继承。
65 2

热门文章

最新文章