final 关键字
1,空白final
package example;
class People{
private int i;
People(int ii){
i=ii;
}
}
public class Test{
private final int i=0;
private final int j; //空白final必须在每个构造器中用表达式对final进行赋值
private final People p; //否则会提示可能空白终态字段 可能尚未初始化
Test(){
j=1;
p=new People(1);
}
Test(int x){
j=2;
p=new People(x);
}
public static void main(String[] args) {
Test a=new Test(20);
}
}
2,final参数
package example;
class Gizmo{
public void spin(){}
}
public class Test{
void with(final Gizmo g){ //java允许在参数列表中以声明的方式将参数指明为final
//这意味着你无法改变在方法中更改参数引用的对象
// g=new Gizmo(); //illegal--g is final
}
int g(final int i){
// i++; //can't change
return i+1;
}
}
3
final和private
类中所有的private方法都隐式的指定为final的,由于无法取用private方法,所以也就无法覆盖他。
可以对private添加final修饰词,但这并不能给该方法增加任何额外意思。
这一问题会造成混淆,可以对private方法试图覆盖,似乎是奏效的,编译器也不会报错。
package example;
class WithFinals{
private final void f(){
System.out.println("WithFinal.f()");
}
private void g(){
System.out.println("WithFinal.g()");
}
}
class OverridingPrivate extends WithFinals{
public final void f(){
System.out.println("OverridingPrivate.f()");
}
public void g(){
System.out.println("OverridingPrivate.g()");
}
}
public class Test{
public static void main(String[] args){
OverridingPrivate op=new OverridingPrivate();
op.g();
op.f();
WithFinals op2= op; //向上转型
//op2.f();
//op2.g(); 编译无法通过
}
}
覆盖只是在某方法是基类的接口的一部分时才会出现,即必须能将一个对象向上转型为它的基类类型
并调用相同的方法。如果某个方法为private,他就不是基类的接口的一部分,它仅仅是一些隐藏于类中的
程序代码,只不过是具有相同的名称而已。由于private方法无法触及而且能有效隐藏,所以除了把他看成
因为他所属的类组织结构的原因而存在外,其他任何任务都不需要考虑到他。
4final类
package example;
final class A{
int i=1;
final int j=2;
void f(){
}
}
/*class B extends A{ //编译错误
}*/
public class Test{
public static void main(String[] args){
A a=new A();
a.i=2;
// a.j=3; 编译错误
}
}
注意,final类禁止继承,所以final中所有方法都是隐式的指定为final。
但,final类的域可以根据个人意愿选择是或者不是final