java 中的 final 关键字

来源:互联网 发布:阿里云百度云腾讯云 编辑:程序博客网 时间:2024/06/15 07:57

        final在Java中是一个保留的关键字,可以声明成员变量、方法、类以及本地变量。一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如果你试图将变量再次初始化的话,编译器会报编译错误。

一。使用 final关键字的 好处

1.1. final关键字提高了性能。JVM和Java应用都会缓存final变量。

1.2. final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。

1.3. 使用final关键字,JVM会对方法、变量及类进行优化。

1.4. 创建不可变类要使用final关键字。不可变类是指它的对象一旦被创建了就不能被更改了。String是不可变类的代表。不可变类有很多好处,譬如它们的对象是只读的,可以在多线程环境下安全的共享,不用额外的同步开销等等。

二。 final 关键字的 基本用法

 2.1. 修饰 类

       当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。

  注意:在使用final修饰类的时候,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。

2.2. 修饰 方法

       所有被final标注的方法都是不能被继承、更改的。

       下面这段话摘自《Java编程思想》第四版第143页:

   “使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。”

   注意:只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为 final 的。即父类的final方法是不能被子类所覆盖的。final 方法比非final方法要快,因为在编译的时候已经静态绑定了,不需要在运行时再动态绑定。

2.3. 修饰 变量(成员变量和局部变量)

       final 成员变量表示常量,只能被赋值一次,赋值后值不再改变。final修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。

       当final修饰一个 基本数据类型 时,表示该基本数据类型的值一旦在初始化后,值 便不能发生变化;如果final修饰一个 引用类型 时,则在对其初始化之后便不能再让其指向其他对象了(即 引用数据类型不可变的是其引用),但该引用所指向的对象的 内容 是可以发生变化的。本质上是一回事,因为引用的地址是一个值,final要求值,即地址的值不发生变化。

三。关于 final 的重要知识点

 3.1. final关键字可以用于成员变量、本地变量、方法以及类。

 3.2. final成员变量必须在声明的时候初始化或者在构造器中初始化或者调用this()初始化,否则就会报编译错误;没有在声明时初始化final变量的称为空白final变量(blank final variable)

 3.3. 不能够对final变量再次赋值,本地变量必须在声明时赋值。

 3.4. final方法 不能被 重写;final类 不能被 继承;final变量 不能被 修改

 3.5. 在 匿名类 中所有变量都必须是final变量。

 3.6. final关键字容易与finalize()方法搞混,后者是在Object类中定义的方法,是在垃圾回收之前被JVM调用的方法。

 3.7. 接口中声明的所有变量本身是final的。

 3.8. final 和 abstract 这两个关键字是反相关的,final类就 不 可能是abstract的。

 3.9. final方法在编译阶段绑定,称为静态绑定(static binding)。

 3.10. 将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化。

 3.11. 按照Java代码惯例,final变量就是常量,而且通常常量名要大写。

 3.12. 局部内部类和匿名内部类只能访问局部final变量。

 3.13. final的作用是用来保证变量不可变,而static作用于成员变量用来表示只保存一份副本。

 3.14. static final用来修饰成员变量和成员方法,可简单理解为“全局常量”。

 3.15. 对于集合对象声明为final指的是引用不能被更改,但是你可以向其中增加,删除或者改变内容。如:

   

   private final List list = new ArrayList();
   list.add(“home ”);      //valid
   list = new Vector();       //not valid