美文网首页
final关键字详解

final关键字详解

作者: Tiger_Lam | 来源:发表于2021-10-13 22:18 被阅读0次

    final的作用

    final根据修饰位置的不同作用也不相同,针对三种情况:
    1)修饰变量,被final修饰的变量必须要初始化,赋初值后不能再重新赋值。
    注意:局部变量不在我们讨论的范畴,因为局部变量本身就有作用范围,不使用private、public等词修饰。
    2)修饰方法,被final修饰的方法代表不能重写。
    3)修饰类,被final修饰的类,不能够被继承。
    注意:final修饰的类,类中的所有成员方法都被隐式地指定为final方法。

    所有的final修饰的字段都是编译期常量吗?

    并不是,比如String

    如何理解private所修饰的方法是隐式的final?

    不太正确,private可以通过反射的方式去修改,final如果通过反射的方式去修改值的话,必须要避开编译的自动优化,例如这样:private final int a=(null!=null?0:1);

    Java反射机制可以动态修改实例中final修饰的成员变量吗?

    回答是分两种情况的。

    1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了。

    2. 当final修饰的成员变量在定义的时候并没有初始化值的话,那么就还能通过java反射机制来动态修改它的值。

    public class MainTest {
    
    
    public static void main(String[] args) {
    
    try {  
                A a = new A();  
      
                Field field = a.getClass().getDeclaredField("a");  
      
                field.setAccessible(true);  
      
                field.set(a, 2);  
      
                System.out.println(field.get(a));  //打印  2
                System.out.println(a.getA()); //打印  1 为什么这里不是2
            } catch (SecurityException e) {  
                e.printStackTrace();  
            } catch (NoSuchFieldException e) {  
                e.printStackTrace();  
            } catch (IllegalArgumentException e) {  
                e.printStackTrace();  
            } catch (IllegalAccessException e) {  
                e.printStackTrace();  
            }  
       }
    }
    
    
    class A {  
        private final int a=1 ;  
        
       
        
        public int getA()
        {
        return this.a;
        }
    }
    
    

    如果把A修改为

    class A {  
        private final int a ;  //区别在于这里没给a直接赋值,而是用构造函数
        
        public A()
        {
            this.a=1;
        }
        
        public int getA()
        {
            return this.a;
        }
    }
    
    System.out.println(field.get(a));  //打印  2
    System.out.println(a.getA()); //打印  2  为什么这次是2了
    

    原因在于编译期间final类型的数据自动被优化了,即:所有用到该变量的地方都呗替换成了常量。所以 get方法在编译后自动优化成了return 1 ; 而不是 return this.a;

    要想不被自动优化,可以把初始化代码改成:private final int a=(null!=null?0:1);

    所以说如果想要通过反射去修改final的值,必须要避开编译期间的自动优化

    final方法可以被重载吗?可以

    父类的final方法能不能够被子类重写?不可以

    相关文章

      网友评论

          本文标题:final关键字详解

          本文链接:https://www.haomeiwen.com/subject/ekieoltx.html