• JAVA中final关键字的作用


    final关键字的功能概述

      在Java中,关键字 final 的意思是终态,可以用于声明变量、方法和类,分别表示变量不可变,方法不可被覆盖,类不可被继承。下面进行详细阐述。

    1、用来修饰变量

      当使用final修饰一个变量(属性)时,这个属性就成为一个常量。此时可以考虑赋值的位置有直接初始化、代码块中初始化和构造器中初始化。

    final修饰局部变量

      使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参以后,就只能在方法体内使用此形参,而不能重新赋值。形参是局部变量,其作用域是整个方法体。

    public void localArg(final int arg){
        arg = 20;//编译不通过,异常信息【Cannot assign a value to final variable 'arg'】
        System.out.println(arg);
    }
    public void localArg(){
        final int ARG = 10;//常量,基本类型变量
        ARG += 20;//编译不通过
    }
    
    

    final关键字修饰成员变量

      对于成员变量来说,一旦使用final关键字,也是不能再次改变。
      和局部变量的不同点在于,成员变量需要有默认值,因此必须手动赋值。final修饰的成员变量赋值途径有两个,而且只能二者选择其一:①在定义的时候直接赋值,②在构造方法体里面赋值,此时必须保证所有重载的构造方法都对final修饰的成员变量赋值。

    public User(Long id, int age, String name) {
        super();
        this.id = id;
        this.age = age;
        this.name = name;
        var = 91;
    }
    
    //定义时直接赋值
    private final int a = 32;
    //使用构造方法赋值
    private final int var;
    public User() {
        var = 90;
    }
    

    final修饰基本类型变量

      当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。上文中的int ARG就属于基本类型变量。

    final修饰引用类型变量

      当使用final修饰引用类型变量时,比如对象和数组等,不可变的含义就是地址值不能改变,但是该地址指向的对象的内容是可以改变的。它保存的仅仅是一个引用,final只能保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以改变。
      这里引用一个网上常见的例子,以说明final修饰基本类型变量和引用类型变量的区别。

    //final修饰基本类型变量和引用类型变量的区别
    import java.util.Arrays;
    class Person
    {
        private int age;
        public Person(){}
       // 有参数的构造器
        public Person(int age)  {
            this.age = age;
        }
        public void setAge(int age){this.age = age;}
        public int getAge(){return age;}
    }
    public class FinalReferenceTest {
        public static void main(String[] args)  {
            //final修饰数组,iArr是一个引用变量
            final int[] iArr = {5,6,12,19};
            System.out.println(Arrays.toString(iArr));
            //对数组元素排序,合法
            Arrays.sort(iArr);
            System.out.println(Arrays.toString(iArr));
            //对数组元素赋值,合法
            iArr[2] = -8;
            System.out.println(Arrays.toString(iArr));
            Arrays.sort(iArr);
            System.out.println(Arrays.toString(iArr));
            //下面语句对iArr重新赋值,非法
            //iArr = null;
    
    
            //final修饰Person变量,p是一个引用变量
            final Person p = new Person(45);
            //改变Person对象的age实例变量,合法
            p.setAge(23);
            System.out.println(p.getAge());
            //下面语句对p重新赋值,非法
            //p = null;
        }
    }
    

    2.用来修饰方法

      当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。例如Object类中的getClass()方法。使用IDEA,在User类中重写 Object类中的getClass()方法,则可以看到如下异常信息,提示方法无法被子类重写。

    'getClass()' cannot override 'getClass()' in 'java.lang.Object'; overridden method is final
    

      在java中,把一个类中的方法修饰为final,意味着两个功能,第一点是该方法不能被重载,第二点是允许编译器将所有对此方法的调用转化为inline(行内)调用的机制,它会使你在调用final方法时,直接将方法主体插入到调用处,而不是进行例行的方法调用,例如保存断点,压栈等,这样可能会使你的程序效率有所提高。第二点也同时提醒我们,要谨慎的将方法定义为final,因为如果方法很庞大,你的代码量就会因为inline而迅速膨胀,可能反而会影响效率。

    3.用来修饰类

      当用final修改类时,该类成为最终类,无法被继承。简称为“断子绝孙类”。

    /***
    * final用法3:修饰类,则该类成为最终类,无法被继承 
    *下面这行代码放开注释,就会抛出异常提示
    */
    //class MyString extends String{}
    
    

      比如常用的String类、System类、StringBuffer类,它们都是最终类。定义断子绝孙类的目的是提高安全性,增强程序的可读性。
      老铁们, 因个人能力有限,难免有瑕疵,如果发现bug或者有更好的建议,那么请在文章下方留言!

  • 相关阅读:
    700. Search in a Binary Search Tree
    100. Same Tree
    543. Diameter of Binary Tree
    257. Binary Tree Paths
    572. Subtree of Another Tree
    226. Invert Binary Tree
    104. Maximum Depth of Binary Tree
    1、解决sublime打开文档,出现中文乱码问题
    移植seetafaceengine-master、opencv到ARM板
    ubuntu16.04-交叉编译-SeetaFaceEngine-master
  • 原文地址:https://www.cnblogs.com/east7/p/13939379.html
Copyright © 2020-2023  润新知