欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

深入解析final关键字的用法

发布时间:2024/9/27 47 豆豆
生活随笔 收集整理的这篇文章主要介绍了 深入解析final关键字的用法 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

夫陶公清风千古,余又何人,敢称庶几

个人博客地址:http://blog.breez.work


文章目录

  • 介绍
    • 解析
      • final属性
      • final方法
      • final参数
      • final类

介绍

final用于声明属性【属性不可变】、方法【方法不可覆盖】、(除了抽象类)【类不可被继承】

解析

final属性

被final修饰的变量不可变。【引用不可变】

public class FinalTest {public static void main(String[] args) {final StringBuffer s = new StringBuffer("Hello");s.append(" World");System.out.println(s); //输出Hello World} }
public class FinalTest {public static void main(String[] args) {final StringBuffer s = new StringBuffer("Hello World");s = new StringBuffer("Hello world"); //编译报错} }

从上面可以看出final指的是引用不可变,即它只能指向初始化时指向的那个对象,不关心指向对象内容的变化。所以被final修饰的变量必须被初始化。

如何初始化:

  • 在定义的时候初始化
  • final String name="BreezAm"; name="change"; //编译错误
  • final成员变量可以在初始块中初始化,但不可在静态块中初始化。
    • 在初始化块中初始化:【编译通过】
    public class FinalTest {private final String name;//定义一个成员变量{name = "BreezAm";//初始化块中初始化成员变量name}public static void main(String[] args) {FinalTest test = new FinalTest();String name = test.name;System.out.println(name);//BreezAmtest.name="change";//编译报错} }

    试图在静态初始化块中初始化final变量【编译报错】

    public class FinalTest {private final String name;// 编译报错static{name = "BreezAm"; //编译报错,就算name定义时已经被初始化此处编译期也会报错}public static void main(String[] args) {FinalTest test = new FinalTest();String name = test.name;System.out.println(name);//BreezAm} }
  • 静态final成员变量可以在静态初始化块中初始化,但不可以在初始化块中初始化。
    • 在静态初始化块中初始化成员变量【编译通过】
    public class FinalTest {private static final String name;// 定义一个静态、不可变的变量static {name = "BreezAm";//在静态初始化块中初始化}public static void main(String[] args) {String name = FinalTest.name;System.out.println(name);//BreezAm} }
    • 试图在静态初始化块中初始化成员变量【编译报错】
    public class FinalTest {private static final String name;// 编译报错{name = "BreezAm";//在初始化块中初始化}public static void main(String[] args) {String name = FinalTest.name;System.out.println(name);//BreezAm} }
  • 在类的构造器中初始化,但静态final成员变量不可以在构造函数中初始化。
    • 在构造器中初始化非静态final成员变量【编译通过】
    public class FinalTest {private final String name;// 定义一个成员变量【未初始化】public FinalTest() {name = "BreezAm";//在构造器中初始化final类型的成员变量}public static void main(String[] args) {FinalTest test = new FinalTest();String name = test.name;System.out.println(name);//BreezAm} }

    final方法

    当一个方法被声明为final时,该方法不允许任何子类重写这个方法,但子类仍然可以使用这个方法。[注意:final方法可以被重载]


    另外,还有一种被称为inline(内联)的机制,当调用一个被声明为final的方法时,直接将方法主体插入到调用处,而不是进行方法调用(类似于C++中的inline),这样做可以提高程序的效率

    案例:

    /*** 父类*/ public class Father {/*** 编写一个final方法*/public final void doAction(){System.out.println("我是final方法、我不可以被重写,但是你可以用噢!渣女!!");} }

    子类试图重写final方法【编译报错】

    /*** 子类*/ public class Children extends Father {public final void doAction(){ //编译报错、因为父类doAction方法是final类型的,所以不可以被重写}public static void main(String[] args) {} }

    使用父类中的final方法【编译通过】

    /*** 子类*/ public class Children extends Father {public static void main(String[] args) {Children children = new Children();children.doAction();} }

    输出:

    我是final方法、我不可以被重写,但是你可以用噢!渣女!!

    子类重载父类中的final方法

    /*** 子类*/ public class Children extends Father {/*** 重写父类中被声明为final的方法* @param a* @param b*/public final void doAction(int a,int b){ // 可以被重载,哈哈,被我发现了System.out.println("a:"+a);System.out.println("b:"+b);}public static void main(String[] args) {Children children = new Children();children.doAction(20,30);} }

    输出:

    a:20 b:30

    final参数

    用来表示这个参数在这个函数内部不允许被修改

    案例:

    public class FinalTest {/*** 编写一个带参数为final的方法** @param name*//*public void doActionFinal(final String name) {name = "我想修改name,但是编译报错了,难过!!"; //编译不通过}*//*** 编写一个带非final参数的方法** @param name*/public void doAction(String name) {System.out.println("修改前:" + name);name = "name参数不是final的,我修改成功了,一个字:巴适!"; //编译通过System.out.println("修改后: " + name);}public static void main(String[] args) {FinalTest test = new FinalTest();//test.doActionFinal("BreezAm");test.doAction("BreezAm");} }

    输出:

    修改前:BreezAm 修改后: name参数不是final的,我修改成功了,一个字:巴适!

    final类

    当一个类被声明为final时,此类不能被继承,所有的方法都不能被重写。但这并不表示final类的成员变量也是不可变的,要想做到final类的成员变量不可改变,必须给成员变量增加final修饰。注意:一个类不能即被声明为abstract,又被声明为final【抽象类不能声明为final】。

    试图继承被声明为final的类【编译失败】

    /*** 父类*/ public final class Father { } /*** 子类*/ public class Children extends Father { //编译报错}

    试图将一个abstract类声明为final【编译失败】

    /*** 父类*/ public final abstract class Father { //编译失败,抽象类不能声明为final}

    修改final类的成员变量

    /*** 父类*/ public final class Father {private String name = "BreezAm";private final int num = 2018010110;public void doAction() {name = "清风";//修改final类的非final成员变量 编译通过num = 2019010110;//修改final类的final成员变量 编译失败} }

    创作挑战赛新人创作奖励来咯,坚持创作打卡瓜分现金大奖

    总结

    以上是生活随笔为你收集整理的深入解析final关键字的用法的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。