• final关键字细节


      final关键字在java中是一个很重要的关键字,其实按照其字面意思理解,就可以一窥这个关键字端倪,final的本意是最终的。所谓最终的,其最重要的特征就是不能修改,由此衍生出的许多细节均应以这个特征作为基础。

      final可以修饰类、方法、变量。变量包括成员变量和局部变量。

      1.修饰类

      final修饰过的类不能被继承,如下的代码在ide中是会报错的。

      

    final class Father{
        
    }
    //The type son cannot subclass the final class Father
    class son extends Father{
        
    }

      2.修饰方法

      final关键字修饰过的方法不能被子类重写。

      

    class Father {
        public final void father_func() {
            System.out.println("father function");
        }
    
    }
    class son extends Father {
        //Cannot override the final method from Father
        public void father_func() {
    
        }
    }

      其实不管是final修饰的类不能被继承,还是final修饰的方法不能被子类重写,都是要保证这个类,这个方法时最终的,不能再被更改。这也符合final的本意。

      3.修饰成员变量

      final修饰的成员变量只能被赋值一次,而且必须在声明的同时或者构造函数中显式赋值,然后才能使用。否则ide会给出提醒。因为不像普通的成员变量,即便不显式初始化,系统也会默认初始化。

      以下代码会出错。

    public class FinalDemo {
        final Father f;
        //The blank final field f may not have been initialized
        public FinalDemo(){
            
        }
        public static void main(String args[]) {
    
        }
    
    }
    
    class Father {
        public final void father_func() {
            System.out.println("father function");
        }
    
    }

      这样写才正确 

    public class FinalDemo {
        final Father f;
        public FinalDemo(){
            f=new Father();
        }
        public static void main(String args[]) {
    
        }
    
    }

      4.修饰局部变量

      final修饰的局部变量只能被赋值一次。有时候我们方法的形式参数(这也相当于一个局部变量)用final 来声明,目的就是告诉编程的人,不要再在方法体里面给这个变量去赋值了

      如下代码是错误的。

    class Father {
        public void func(final int y){
            //The final local variable y cannot be assigned. It must be blank and not using a compound assignment
            y=3;
            System.out.println(y);
        }
    
    }

      既然y被final修饰,它就不能在方法体中继续赋值。修改成如下,并调用才是正确的。

      

    public class FinalDemo {
        public static void main(String args[]) {
            Father f=new Father();
            f.func(1);
            f.func(3);
        }
    
    }
    
    class Father {
        public void func(final int y){
            System.out.println(y);
        }
    
    }

      上述执行的结果是1和3。两次调用func,分别传入1和3给final形参y。此处不要认为我修改了y的值,我调用了两次func方法,两次的局部变量并不是同一个。所以不存在重复赋值的说法。

      如果在方法体中定义一个final类型的局部变量,则只能给他赋值一次,不能重复赋值,这很好理解。当然也不能不赋值,这是最基本的,方法体中不管是不是final修饰的局部变量,都应该先被赋值才能使用。

      5.如果一个类中的成员变量,除了用final修饰,还加上了static,那么他就有两层的属性,首先是静态的,可以直接通过类名直接访问得到。其次它是不可再被修改的。那么这种类型的变量我们可以称之为静态常量,它必须在声明的时候就直接显式初始化,即便在构造函数中都不能再初始化(可以理解为静态变量并不需要实例化就可以访问到,所以有可能不会执行到构造函数里面的代码,这就无法保证这个final变量一定会被初始化,于是干脆在声明的时候就初始化,最为保险)

      这种静态常量可以直接通过类名来访问,当我们再加上一个访问权限修饰符,比如public以后,这就成为了一个全局的常量,在整个项目中都能被访问到。在项目中,我们经常在一个类中写满了public static final类型的变量,并且命名为constant.java。然后通过constant.x来获取这些常量。

      

      

  • 相关阅读:
    .netcore利用DI实现级联删除
    识别手写数字增强版100%
    嗨!请查收这道有趣的面试题
    理解TCP/IP协议栈之HTTP2.0
    基于Redis的分布式锁和Redlock算法
    从生日悖论谈哈希碰撞
    Redis面试热点工程架构篇之数据同步
    Redis面试热点之底层实现篇(续)
    saltstack安装+基本命令
    25个iptables常用示例
  • 原文地址:https://www.cnblogs.com/roy-blog/p/7670327.html
Copyright © 2020-2023  润新知