JAVA中的修饰变量final

在Java中,`final` 关键字是一个非常重要的修饰符,它用于表示一个变量、方法或类是不可变的。当`final`用于变量时,它意味着这个变量的值一旦被初始化之后就不能被改变。这对于定义常量非常有用,因为它确保了变量在整个程序运行期间都保持其初始值不变。

final 变量的基本用法

在Java中,`final` 变量可以是基本数据类型的变量,也可以是引用类型的变量。但是,当`final`用于引用类型的变量时,它指的是引用本身是不可变的,而不是对象本身不可变。也就是说,你不能让`final`引用指向另一个对象,但是你可以修改该对象内部的状态(如果对象是可变的)。

示例代码

java 复制代码
public class FinalExample {
    // final 修饰的基本数据类型变量
    final int MAX_VALUE = 100; // MAX_VALUE的值被初始化为100,之后不能被修改

    // final 修饰的引用类型变量
    final String NAME = "Java"; // NAME的引用指向"Java"字符串,之后NAME不能指向另一个字符串

    public static void main(String[] args) {
        // 尝试修改final变量的值,会编译错误
        // MAX_VALUE = 200; // 编译错误

        // 尝试让final引用指向另一个对象,会编译错误
        // NAME = "Python"; // 编译错误

        // 但是,如果对象是可变的,我们可以修改对象内部的状态
        // 假设我们有一个可变的Person类
        final Person person = new Person("Alice", 25);
        // 下面的操作是合法的,因为我们没有改变person的引用,只是修改了对象的状态
        person.setName("Bob");

        // 打印修改后的信息
        System.out.println(person.getName()); // 输出: Bob
    }

    // 假设的Person类
    static class Person {
        private String name;
        private int age;

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        // ... 其他方法
    }
}

final 变量的初始化

`final` 变量必须在声明时或者在构造器中初始化。对于类的成员变量,如果`final`变量没有在声明时初始化,那么它必须在每个构造器中初始化。

示例代码

java 复制代码
public class FinalInitialization {
    // 在声明时初始化
    final int constantValue = 42;

    // 引用类型也可以在声明时初始化
    final String greeting = "Hello, World!";

    // 类的成员变量,在构造器中初始化
    final int value;

    // 无参构造器
    public FinalInitialization() {
        // 必须在这里初始化value
        value = 10;
    }

    // 带参构造器
    public FinalInitialization(int initialValue) {
        // 也可以在这里初始化value
        value = initialValue;
    }

    public static void main(String[] args) {
        FinalInitialization obj1 = new FinalInitialization();
        FinalInitialization obj2 = new FinalInitialization(20);

        System.out.println(obj1.value); // 输出: 10
        System.out.println(obj2.value); // 输出: 20
    }
}

final 变量的注意事项

  • 初始化时机:`final` 变量必须在声明时或者在构造器中初始化。
  • 空白`final`:如果`final`变量在声明时没有初始化,那么它就是一个空白`final`变量,必须在构造器中初始化。
  • 引用与对象:当`final`用于引用类型的变量时,它指的是引用本身是不可变的,而不是对象本身不可变。这意味着你不能将`final`引用指向另一个对象,但是你可以修改该对象内部的状态(如果对象是可变的)。
  • 不可变性:在Java中,如果一个类的所有成员变量都是`final`的,那么这个类通常设计成不可变的(immutable)。不可变对象一旦创建,其状态就不能被改变,这样的对象是线程安全的。

final 变量的作用

    1. 定义常量:`final` 变量通常用于定义常量,比如数学中的π(π)值、物理中的光速等。
    1. 提高安全性:通过防止变量被意外修改,`final` 变量可以提高代码的安全性和稳定性。
    1. 提升性能:在某些情况下,编译器可以通过优化`final`变量来提高程序的性能,因为`final`变量的值在编译时就是已知的。
    1. 设计不可变对象:通过将所有成员变量都声明为`final`,可以设计不可变对象,这样的对象一旦创建,其状态就不能被改变。
    1. 多线程安全:在多线程编程中,使用`final`关键字可以确保共享数据的不可变性,从而避免并发问题。

示例代码 - 使用final设计不可变类

java 复制代码
public class ImmutablePerson {
    // 使用final修饰符来声明成员变量为常量
    private final String name;
    private final int age;
    private final String address;
  
    public ImmutablePerson(String name, int age, String address) {
        this.name = name; // 由于是final的,这里的赋值操作不能再改变name的值了
        this.age = age; // 同上对于age和address来说也是一样的情况
        this.address = address; // final引用指向的内容不能再改变,但是可以修改引用的对象里的可变的属性值(如String里的value)
    }
  
    // getter方法略...
  }

注意: `String`类是不可变的,所以虽然我们使用了 `address` 的引用初始化了一个 `String`,但是我们无法去改变这个 `String` 的值,因为它是不可变的,这也就是为什么我们说这个 `ImmutablePerson` 是不可变的了,因为他的所有属性都是不可变的,所以这个类的实例也是不可变的。

相关推荐
XiaoLeisj40 分钟前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck42 分钟前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
dayouziei42 分钟前
java的类加载机制的学习
java·学习
励志成为嵌入式工程师2 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉2 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer2 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
码农小旋风2 小时前
详解K8S--声明式API
后端
Peter_chq2 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml43 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~3 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端