final关键字在Android和Java中使用总结

  1. final作用于类上:表示该类不可被继承 

    某些类在设计的时候,可能出于安全的考虑,不希望被继承,例如String类。final类中的属性和方法可以是final或者非final,但是由于不能被继承,也就意味着final类中的方法都是final的,当然你也可以显式去指定。在《Effective Java》一书中,有句名言“design and document for inheritance or else prohibit it”,用我们的话来解读就是尽可能的将类设计成final的。在Kotlin中就是这么做的,一个类或者方法默认情况下都是final的,如果你要想类或者方法被子类继承或重写,你需要显式地使用open关键字。

  2. final作用于方法上:表示该方法不能被重写

    • final和abstract关键字能一起使用吗?答案是不能,因为它们所要表达的语法含义刚好是矛盾的,前者表示方法不能被重写,而后者表示该方法需要被子类去实现、去重写。
    • private方法隐式地被声明成final.因为private方法在子类中是不可见的,当然也就不能被重写,自然而然也就是final的
  3. final作用于类的属性上:表示该属性值不能被修改

    • final属性可以在哪些地方被初始化?
      • 如果修饰的是实例变量,那么可以在声明处、构造器以及实例代码块中进行初始化
      • 如果修饰的是static变量,那么可以在声明处以及静态代码块中进行初始化
    • 为什么Android开发的相关资料上都建议将常量定义成static final的?

      当然目的是为了性能优化。但是并不是所有情况下都能起到性能优化的作用:当用来修饰基本数据类型或者是String类型(字面量的形式,非引用类型)时,是可以起到性能优化的作用的;当用来修饰引用类型时,起不到任何优化的作用。原因是由于:在编译期,对于static final修饰的基本数据类型域会在引用的地方直接替换成立即数,对应的字节码指令就是const/n(n表示几字节的常量);对于static final修饰的String类型(非引用)在引用处被常量池索引id所替代,它对应的字节码指令const-string;而对于static final修饰的引用类型,在访问处对应的字节指令为sget,sget指令相比较前两者,虚拟机在解释时要做的工作会更多,会更加繁重。

    • 通过反射修改final修饰的域时,注意Android和Java中是不同的,在Android的Field类是用accessFlags字段来表示的,而在Java中的Field类是用modifiers字段来表示的。

    • 在多线程环境中,将类中的属性声明为final时,有利于线程安全,因为何时何地,你对final属性的访问结果都是一致的

  4. final作用于局部变量上:表示该属性值不能被修改

    • Java8之前的语法要求:当在一个匿名内部类中访问外部的局部变量时,在Java8之前,是需要显式地将被访问的局部变量声明成final的,至于为什么大家可以看这篇文章
    • 编码习惯:我们在阅读某些框架源码时,经常在方法中对于成员域的访问时,都是先用一个局部变量来接收,之后对于成员域的访问都是使用这个局部变量的。这点很好理解,表示在这个方法里面对于成员域执行的是只读操作,这样在排查或者跟踪成员域的变化流程时,会很方便。而且在这种情况下,这个局部变量都会用final修饰,可能是为了强调这种只读性吧。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值