在java中,存在着final这么一个关键字,实际上,使用final声明的类实际上就属于断子绝孙的类,因为不能被继承,也可以称为太监类。那么final关键字可以用作什么声明呢?
1、 声明变量
2、 声明方法
3、 声明类
4、 声明对象引用
5、 用于匿名内部类中方法的参数传递
声明变量
在声明变量的时候,只要用final关键字声明,那就表示这个变量是一个编译时常量,不能改变。在声明常量的时候,一般命名都是大写字母。
private final String NAME=”test”; |
如果同时用static和final声明一个常量的话,表示这个常量是全局常量
声明方法
用final声明方法的话,表示这个方法是不能被子类覆写。在这里顺便提下,大家应该知道在父类中用private声明的方法时无法被覆写,其实,类中所以private方法都是隐式的被指定成final的,所以不能被子类覆写。
声明类
如果是声明类的话,那么这个类是不能被继承的,也就是说这个类是无子类的,可以称为太监类。因为final声明的类是无法被继承的,所以该类中的全部方法都是被指定为final的,也就是根本就无法进行覆写。
声明对象引用
其实上面的三点很多人都是很清楚的,但是final还可以进行对象引用的声明,这点可能会容易被大家忽略,其实声明对象引用是可以和声明变量放在一起说的,不过在这里还是独立出来讲更好一点。
用final声明对象引用的时候,表明这个对象引用已经指定了对象实例了,那么这个时候就不能指向新的引用,但是引用的值是可以改变的。如
public static void main(String[] args) { final int[] temp = { 1, 2, 3, 4, 5 }; for (int i = 0; i < temp.length; i++) { temp[i] += 1; } for (int i = 0; i < temp.length; i++) { System.out.println(temp[i]); } } |
输出的结果会是数组temp的值全部+1了。也就是说,其实final指定对象引用的时候,指的是对象引用无法指向新的引用,而不代表值是不变的,所以这是跟声明变量由区别的。
既然可以声明数组引用,当然也可以声明类对象的引用咯,其实原理是一样的。
这个时候有人会问,如果我只声明temp对象引用,但不进行赋值呢?
java是允许生成“空白final”的,也就是说允许只声明一个对象引用,但不给他指定初值。这个时候编译器会确保空白final在使用前必须被初始化,这样一个类中的final域就可以做到根据对象而有所不同。
定义空白final的话,该空白final的引用一定要在类的构造方法中进行赋值,否则的话编译器会报错,如果重载了类的构造方法,那么重载的构造方法也一定要对空白final的引用进赋值,同理,声明空白的变量,如final int a也是一样的。
class A{ int a; public A(int i){ //构造方法 a=i; } } class B{ final A a; //空白final,必须在类的构造方法中实例化,不然会报错 int b; // public void fun(){ // a=new A(1); //无法完成实例化 // } public B(int i){ //重载构造方法,构造方法中一定要对A进行实例化,不然报错 a=new A(i); } public B(){ //构造方法中一定要对A进行实例化,不然报错 a=new A(1); } } |
用于匿名内部类方法的参数传递
final关键字还有一个易被大家忽略的作用,那就是用于在匿名内部类的方法的参数传递中。如果使用了匿名内部类,而且类中方法需要引用到外部类方法中的参数,那么这些参数就要定义成final,不然会报错。
class Contents{} public Contents contents(final int a){ return new Contents(){ int b; public void fun(){ System.out.println(this); b=a; } }; } |