JAVA的final修饰符

本文详细解析Java中final关键字的使用,包括final修饰类、变量、方法的特点,以及如何利用final创建不可变类,强调其在确保代码稳定性和安全性方面的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

final

final可用于修饰类, 变量和方法。用于表示它修饰的类,方法,变量不可改变。

final成员变量

final修饰的成员变量必须由程序员显式的指定初始值。
类变量: 只能在 静态初始化块 或 声明类变量 时指定初始值。
实例变量: 只能在 非静态初始化块, 声明该实例变量 或 构造器中 指定。
初始化之前不能使用变量。

public class FinalVarTest {
    final  int a = 1;
    final  String str;
    final  String str2;
    final static int b;
    {
        str = "hello";
    }

    static {
        b = 2;
    }

    public FinalVarTest(){
        str2 = "1";
    }

    public FinalVarTest(String a){
        str2 = "3";
    }

    public static void main(String[]  args){
        FinalVarTest varTest1 = new FinalVarTest();

        FinalVarTest varTest2 = new FinalVarTest("b");
        System.out.println(varTest1.str2);  // 1
        System.out.println(varTest2.str2);  // 3
    }
}

final局部变量

final修饰的局部变量, 赋值后不能被修改。

    public static void main(String[]  args){
        final String s1 = "1";
        final String s2;
      
        s2 = "2";
    }

final 修饰形参

    public void test(final int a){
        a = 2;  //报错, 不能修改
    }

形参是根据传入的参数完成初始化, 不能被赋值。

final 修饰引用类型变量

引用类型变量,保存的只是一个引用,final只保证所引用的地址不会改变,即一直引用一个对象,但这个对象可以发生改变。

    public static void main(String[]  args){
        final int[] arr = {3, 4, 1, 2};
        System.out.println(Arrays.toString(arr));  //[3, 4, 1, 2]

        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr)); //[1, 2, 3, 4]

        arr[2] = 8;
        System.out.println(Arrays.toString(arr)); //[1, 2, 8, 4]

        final Dog dog = new Dog("1", "haha");
        dog.setId("2");
        System.out.println(dog.getId());  // 2
		
		dog = null;  //报错, 不能修改
    }

可执行"宏替换"

当final变量的值在编译阶段就被确定下来, 则相当于一个直接量。本质上就是一个"宏变量"。
编译器会把用改变量的地方直接替换成该变量的值。

final方法

final方法不可被重写。
Object 类的 getClass() 方法,就是 final 修饰, 不能被子类重写

	public final native Class<?> getClass();

如果父类的 final方法是 private 方法, 则子类可以定义跟这个方法完全相同的方法,private方法子类无法访问, 等于定义一个新方法.
final不能被重写,重载是不影响的。

    public final void testFun(){}
    public final void testFun(int a){}

final类

final修饰的类,不能有子类。

public final class FinalVarTest {}
class Sub extends FinalVarTest{}  //编译错误, 不能继承

不可变类

不可变类 immutable , 创建实例后,实例变量是不可改变的。
Java的8个包装类和 java.lang.String 都是不可变类。

String sx = new String("hello");

String 类提供实例变量保存 “hello”, 无法修改这个实例变量的值,String类没有提供修改他们都方法。
创建自定义的不可变类, 遵守下面规则:

  1. 使用 private 和 final 修饰符来修饰该类的成员变量。
  2. 提供带参的构造器, 根据参数初始化成员变量
  3. 为该类成员变量提供 getter 方法, 不提供 setter 方法, 普通方法不能修改 final 成员变量
  4. 如有必要,可以重写Object类的 hastCode() 和 equals() 两个方法。
public class Dog {
    private final String id;
    private final String name;

    public String getId() {
        return id;
    }
    public String getName() {
        return name;
    }
    public Dog(String id, String name) {
        this.id = id;
        this.name = name;
    }

    //重写 equals 方法
    public boolean equals(Object obj){
        //同一个对象
        if(this == obj){
            return true;
        }
        // obj是 Dog对象
        if(obj != null && obj.getClass() == Dog.class){
            Dog dog = (Dog) obj;
            //当前对象的id 和 obj 对象的 id相等时 返回 true
            if(this.getId().equals(dog.getId())){
                return true;
            }
        }
        return false;
    }
}

不可变类的实例状态不可改变, 可以方便被多个对象共享。
如果频繁使用, 可以考虑缓存这种不可变类实例。
java.lang.Integer 使用了缓存策略, 使用 valueOf()方法创建Integer对象,则会缓存该方法创建的对象。

地址: https://blog.youkuaiyun.com/yonggang7/article/details/86556484

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值