• JavaSE语法中final的作用(面试题经常考!!!)(2.9千字全面解析final关键字)


    1. 面试题

    首先为了大家清楚掌握final关键字的重要性,先上几道面试题给大家看看

    1. 提前批百度一面
      16、final的作用
    2. 滴滴一面
      4.说一下重载和重写, 重写要注意什么(俩小俩等一大) final修饰方法可以重写吗, static方法可以重写吗,
    3. 北森测试开发
      final:string可以被继承吗(我们平时是用的 String 字符串类, 就是用 final 修饰的, 不能被继承)
      final可以修饰抽象类吗

    2. final 关键字

    final关键可以用来修饰变量、成员方法以及类。

    1. 修饰变量或字段,表示常量(即不能修改)

    1. 修饰变量或字段,表示常量(即不能修改)在这里插入图片描述

    1. 修饰成员变量

    1. 修饰成员变量(如果引用是类的成员变量,则必须当场赋值,否则编译会报错。)
    1. 如果final修饰的是类变量,只能在静态初始化块中指定初始值或者声明该类变量时指定初始值。
    2. 如果final修饰的是成员变量,可以在非静态初始化块、声明该变量或者构造器中进行初始值。

    2. 修饰局部变量

    1. 修饰局部变量
      系统不会为局部变量进行初始化,局部变量必须由程序员显示初始化,因此使用final修饰局部变量时,既可以在定义时指定默认值(后面的代码不能对变量再赋值),也可以不指定默认值,而在后面的代码中对final变量赋值(仅一次)
    public class FinalVar {
        final static int a = 2 ; //在静态初始化块中指定初始值或者声明该类变量时指定初始值
        static {
           // a=2;
        }
    
        final int b = 3; //在非静态初始化块、声明该变量或者构造器中进行初始值
        {
           // b =3;
        }
    
    //    public FinalVar(int b) {
    //        this.b = b;
    //    }
    
        public static void main(String[ ]args) {
            final int localA;//局部变量只声明没有初始化,不会报错,与final无关
            localA = 0; //只使用之前一定要赋值
           // localA = 3; 但是不允许第二次赋值
            System.out.println(localA);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3. 修饰基本类型数据和引用类型数据

    1. 修饰基本类型数据和引用类型数据
    1. 如果是基本类型的变量,则其数值一旦初始化之后就不能更改。
    2. 如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象,但是引用的值是可以改变的。
    1. 注:final修饰的常量在编译阶段会被放入常量池中。
    public class FinalReferenceTest {
        public static void main(String []args) {
            final int[] iArr = {1,2,3,4};
            iArr[2] = -3;
          //  iArr = null; //非法,对iArr不能重新赋值
    
            final Person p = new Person(25);
            p.setAge(66);//合法
          //  p =null; //非法
            
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2. 修饰类:表示此类不能被继承,

    1. 修饰类:表示此类不能被继承
      在这里插入图片描述
      在这里插入图片描述
      我们平时是用的 String 字符串类, 就是用 final 修饰的, 不能被继承.

    3. 修饰方法:表示该方法不能被子类重写,可同类重载

    当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。
    使用final方法的原因主要有两个:
    (1)把方法锁定,以防止继承类对其进行更改
    (2)效率,在早期的java版本中,会将final方法转为内嵌调用。但若方法过于庞大,可能在性能上不会有多大提升。因此在最近版本中,不需要final方法进行这些优化了
    final方法意味着“最后的、最终的”含义,即此方法不能被重写。
    注意:若父类中final方法的访问权限为private,将导致子类中不能直接继承该方法,因此,此时可以在子类中定义相同方法名的函数,此时不会与重写final的矛盾,而是在子类中重新地定义了新方法。

    4. 为什么局部内部类和匿名内部类只能访问局部final变量?

    public class Test {
        //编译之后会生成连个class文件,Test.class Test1.class
        public static void main(String[] args) {
            Test t = new Test();
            t.test(20);
        }
            //局部final变量a,b
            public void test(final int b) {
                final int a = 10;
                new Thread() {
                    public void run() {
                        System.out.println(a);
                        System.out.println(b);
    
                    };
                }.start();
    
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    public class OutClass {
        private int age = 12;
    
        public void outPrint(final int x) {
            class InClass {
                public void InPrint() {
                    System.out.println(x);
                    System.out.println(age);
                }
    
            }
            new InClass().InPrint();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    首先需要知道的一点是: 内部类和外部类是处于同一个级别的,内部类不会因为定义在方法中就会随着方法的
    执行完毕就被销毁

    这里就会产生问题,当外部类的方法结束时,局部变量就会被销毁了,但是内部类对象可能还存在(只有没有人再引用它时,才会死亡)。这里就出现了一个矛盾,==内部类对象访问了一个不存在的变量,为了 解决这个问题,就将局部变量复制了一份作为内部类的成员变量,这样当局部变量死亡后,内部类仍然可以访问它,实际访问的是局部变量的"copy",==这样就好像延长了局部变量的生命周期。将局部变量复制为内部类的成员变量时,必须保证这两个变量时一样的,也就是如果我们在内部类修改了成员变量,方法中的局部变量也得跟着改变,怎么解决问题呢?
    就将局部变量设置为final,对它初始化后,我就不让你再去修改这个变量,就保证了内部类的成员变量和方法的局部变量的一致性,这实际上也是一种妥协,使得局部变量与内部类建立的拷贝保持一致。
    总结:外部类的成员变量,可能其实已经销毁了,内部类访问的只是它的拷贝,所以防止内部类修改值,就将 成员变量用 final修饰

    5. static final 用来修饰属性 :全局变量

  • 相关阅读:
    Sqoop的介绍和安装
    Vue.js 事件监听全解析
    【SQL性能优化】从数据页的角度理解B+树查询
    【C语言】通讯录的简单实现
    PAT 1014 福尔摩斯的约会
    【跨境电商】EDM邮件营销完整指南(一):概念,区别与优势
    【逆向】修改LightCycler 96文件Summary日期
    暴力递归转动态规划(二)
    SuperMap iServer11i新功能----图例的发布和使用
    ElasticSearch搜索引擎:数据的写入流程
  • 原文地址:https://blog.csdn.net/m0_63571404/article/details/126244959