关于final的一些细节,我有话要说——深入理解final

·  阅读 269
关于final的一些细节,我有话要说——深入理解final

「这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战」。

茫茫人海千千万万,感谢这一秒你看到这里。希望我的文章对你的有所帮助!

愿你在未来的日子,保持热爱,奔赴山海!!

题记:关于final关键字,它也是我们一个经常用的关键字,可以修饰在类上、或者修饰在变量、方法上,以此看来定义它的一些不可变性!

像我们经常使用的String类中,它便是final来修饰的类,并且它的字符数组也是被final所修饰的。但是一些final的一些细节你真的了解过吗?

从这篇文章开始,带你深入了解final的细节!

👋final的深入了解

🤚深入了解修饰变量

final关键字修饰变量,昨天我们学习了成员变量啦,今天来学习修饰局部变量有什么变化呢,。具体的我们来看看呗!

🖐️修饰局部变量

局部变量声明在方法、构造方法或者语句块中;

修饰局部变量的特点:

  • 对于final修饰局部变量时,如果局部变量已经进行了初始化赋值,则后面就不能对局部变量再次进行更改。
  • 如果final修饰局部变量未进行初始化,则可以进行赋值,**「当且仅有一次」**赋值,一旦赋值之后再次赋值就会出错。

我们还是继续以代码来相会,唯有一看,才能更深入了解!

对于变量来说,它可以有两种数据类型修饰:引用类型和基本数据类型。接下来就以此两种类型来详细说明。

「基本数据变量:」

我们来看下当final修饰基本数据类型变量时,是否真的如以上特点所说的一样。

package com.nz.test;

/**
 * 对修饰局部变量操作详解
 */
public class LocalVariableFinalTest {

    // 测试局部变量
    public void localVariableTest(){
        // 定义基本数据类型变量
        final int localVariable;

        // 可以看到如果我们不去进行初始化操作,也不会有一个编译期间错误
        // 但是如果你没有进行初始化操作,就进行引用的话,就会报未被初始化错误。
        System.out.println("localVariable = " + localVariable);
        
        // 进行初始化赋值操作
        localVariable = 1;
        
        // 一旦进行初始化操作后,就不能再进行赋值操作了
        localVariable = 2;
    }
}
复制代码

我们可以发现,如果我们定义了一个final局部变量的话,发现了两个问题:

  1. 我们可以不必进行初始化赋值操作也不会报错,但是呢,你不能在没有初始化赋值操作时,进行引用,因为它没有默认值,所以你必须进行初始化赋值操作后才能将其引用。
  2. 在被final修饰的局部变量,**「当且仅有一次」**赋值,一旦赋值之后再次赋值就会出错,这个跟之前修饰成员变量的错误一样滴!

「引用类型变量:」

通过上面的基本数据类型的案例,我们发现一旦final修饰的基本数据类型变量进行初始化赋值后,再次赋值就会出错。这代表了基本数据类型的变量是不能再被修改的,那么引用类型变量呢?它能改变吗?接下来我们就来瞧瞧吧!

package com.nz.test;

/**
 * 对修饰局部变量操作详解
 */
public class LocalVariableFinalTest {

    // 在接刚才的方法下,注意得注释掉有报错的地方!
    
    // 测试引用类型局部变量
    public static void main(String[] args) {

        // 定义一名篮球运动员——勒布朗詹姆斯
        final BasketballPlayer james = new BasketballPlayer(36, "勒布朗詹姆斯");

        // 接下来我们对其进行一系列操作!
        // 1. 重新重新初始化赋值!—— 可以看到,引用类型变量也是不能重新赋值
        // 要编译的话,这里得注释掉!
//        james = new BasketballPlayer(36, "老皇帝!");

        // 2. 对james里的参数进行重新赋值
        james.setName("夕阳红队队长!");

        // 可以看到没有报错!那我们试着打印一番,看名字是勒布朗詹姆斯还是夕阳红队队长呢?
        System.out.println("james = " + james.getName());

    }
}

// 定义一个篮球运动员
class BasketballPlayer {

    // 有姓名年龄属性
    private int age;
    private String name;

    // 设计一个有参构造
    public BasketballPlayer(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
复制代码

得到的结果:

james = 夕阳红队队长!
复制代码

我们可以发现有两点问题:

  1. 我们如果要对final引用类型变量进行重新初始化赋值操作的话,一样给你报错,因为被final修饰的引用类型变量一旦初始化赋值后,其指向的对象就是不可变的,而你的new操作,是重新赋予一个新地址,这就当然不行啦!
  2. 而我们当想要对引用类型中的参数进行修改操作,即我们对final修饰的引用类型变量james中的name属性改成夕阳红队队长,是可以修改成功滴!虽然上面的引用地址不能发生变化,但是该地址下的对象属性却是可以改变滴!

小结:

final修饰的引用类型变量一旦初始化赋值后,其指向的对象是不可变的,但是该对象的属性是可变滴!

🌸总结

相信各位看官都对final这一个关键字有了一定了解吧,其实额外扩展自己的知识面也是相当有必要滴,不然别人追问你的时候,你会哑口无言,而一旦你自己每天都深入剖析知识点后,你在今后的对答中都会滔滔不绝,绽放光芒的!!!对吧,我们还有一把东西等着我们探索和摸索中!那我们继续期待下一章的final的内容吧!欢迎期待下一章的到来!

让我们也一起加油吧!本人不才,如有什么缺漏、错误的地方,也欢迎各位人才大佬**「评论」中批评指正!当然如果这篇文章确定对你有点小小帮助的话,也请亲切可爱的人才大佬们给个「点赞、收藏」下吧,「一键三连」**,非常感谢!

学到这里,今天的世界打烊了,晚安!虽然这篇文章完结了,但是我还在,永不完结。我会努力保持写文章。来日方长,何惧车遥马慢!

感谢各位看到这里!愿你韶华不负,青春无悔!

分类:
后端
标签:
分类:
后端
标签: