1 final数据
有时数据的恒定不变是很有用的,比如:
1、一个永不改变的编译时常量
2、一个在运行时被初始化的值,而你不希望它被改变。
对于编译期常量这种情况,编译器可以将该常量值代入任何可能用到它的计算式中,也就是说,可以在编译时执行计算式,这减轻了一些运行时的负担。在Java中,这类常量必须是基本数据类型,并且以final表示,在对这个常量定义的时候,必须对其进行赋值。
一个既是static又是final的域只占据一段不能被改变的存储空间。
对于基本类型,final使数值恒定不变;而对于对象引用,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向其他对象。然而,对象其自身却是可以被修改的,java并未提供使任何对象恒定不变的途径。
根据惯例,既是static又是fina的域(即编辑期常量),将用大表述,并使用下划线分割各个单词。例如:VALUE_TWO
2 final参数
java允许在参数列表中以声明的方式将参数指明为final。这意味着你无法在方法中更改参数引用所向的对象。
class Gizmo{
public void spin(){
}
}
public class FinalArguments {
void with(final Gizmo g){
//! g = new Gizmo(); // Illegal --g is finall
}
void wittOur( Gizmo g){
g = new Gizmo(); // ok --g not finall
g.spin();
}
void f(final int i){
// i++; //不能被改变,因为是final
}
int g(final int i){
return i+1;
}
3.final方法
使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义。这是处于设计的考虑:想要确保在继承中使方法行为保持不变,并且不会被覆盖。过去建议使用final方法的第二个原因是效率。
final 和private关键字
类中所有的private方法都隐式地指定为final的。由于无法取用private方法,所以也就无法覆盖它。
class WithFinals{
private final void f(){
System.out.println("WithFinals.f()");
}
private void g(){
System.out.println("WithFinals.g()");
}
}
class OverridingPrivate extends WithFinals{
private final void f(){
System.out.println("OverridingPrivate.f()");
}
private void g(){
System.out.println("OverridingPrivate.g()");
}
}
class OverridingPrivate2 extends OverridingPrivate{
public final void f(){
System.out.println("OverridingPrivate2.f()");
}
public void g(){
System.out.println("OverridingPrivate2.g()");
}
}
public class FinalOverridingIlluion {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
OverridingPrivate2 op2 = new OverridingPrivate2();
op2.f();
op2.g();
OverridingPrivate op = op2;
//不能call 以下方法
// op.f();
// op.g();
//同理
WithFinals wf = op2;
// wf.f();
// wf.g();
}
}
3 final类
当将某个类的整体定义为final时,就表明你不打算继承该类,而且也不允许别人这样做。