导语:java中的final关键字的含义存在着细微的区别,但通常指“这是不可改变的”.不想改变可能处于两种理由:设计和效率,
两者相差甚远,所以可能被误用 final可以修饰 数据、方法和类。
1.final 关键字修饰的数据
- 有时数据恒定不变是很重要的。
- 一个永不改变的编译时变量
- 一个在运行时被初始化的值而不希望它被改变。
- 编译时常量必须是基本数据类型,并且以final关键字修饰。在对这个常量进行定义的时候,必须对其进行赋值。
- 一个既是static有时final的域只占据一段不能改变的存储空间。
- 对象引用运用final时,final使引用恒定不变,一旦这个引用被初始化指向一个对象时,这个引用就再也不能指向其他对象了,
对象时可以改变的,目前还没有使对象恒定不变的途径。数组也是对象。 public static final int VALUE_THREE = 39;
定义为public 则可以被用于包之外,定义为static,则强调只有一份,定义为final,则说明是一个不可改变的常量。
编码规范:一般全为大写,中间用_隔开,- 当你试图修改一个final时,编译器将会报错。
- 当一个值为静态的时候,在装载时已被初始化,而不是每次创建新对象都会初始化。
空白的final:java允许生成“空白的final”,是指被声明为final但是又未给定初值的域。无论什么情况,编译器都保证空白final在使用前被初始化。
空白final提供了更大的灵活性,
必须在域的定义前或每个构造器中用表达式对final进行赋值,以保证使用前总是被初始化。没有初始化,编译器将会报错。
public class BlankFinal {
private final int j;//空白final
public BlankFinal(){
j = 1;
}
public BlankFinal(int i){
j = 2;
}
}
2.final 参数[方法 内的形参]
class Gizmo{ public void spin(){} } public class FinalArguments { void with(final Gizmo g){} void without(Gizmo g){ g = new Gizmo(); g.spin(); } // void f(final int i){i++;}i在这里是不能改变的 int g(final int i){return i + 1;} public static void main(String[] args) { FinalArguments bf = new FinalArguments(); bf.without(null); bf.with(null); } }
方法f()和g()展示了当基本类型的形式参数被知名为final时,可以读参数,但不可以改变参数。这一特性主要用来想匿名内部类传递参数。
3.final方法
- 使用final关键字可以把方法锁定,以防任何继承类修改它的含义(重写)。想要确保父类中的方法保持不变并不会被覆盖,就是用final关键字。
- 使用final早期的原因是效率,不过已经被淘汰啦,因为应该让编译器和JVM去处理效率的问题,
只有在想明确禁止覆盖的时候,才将方法设置为final.
4.final 和 private
- 类中的private方法都隐式的指定为final的。其他人不可访问
- 由于无法取用private方法,所以也就无法覆盖它。
- 一种特殊的情况:子类中的方法名和父类中的private修饰的方法名相同,编译器不会报错,其实这两个方法并无关系,
一个是父类中的方法,一个是子类中的新方法,他们是两个不同的方法,private是永远不会被覆盖的。
5.接口
- 如果一个方法为private,它就不是基类的接口的一部分。它仅是一些隐藏于勒种的程序代码。
6.final类
- 当想要某个类不能被继承时,就加上final关键字,
- final类中的方法都隐式的指定为时final,因为无法覆盖他们。在final类中给方法添加final修饰词,并没有什么作用。
- final类的域可以根据个人意愿选择是或者不是final。final的域有final的规则存在。
7.final的缺点
- 影响了复用。所以除非特殊需要,不要用这个关键字。
8.淘汰的类
- Vector被ArrayList代替,Hashtable被HashMap代替。