对于final你知道多少?
final关键字的含义会由于语境不同而产生一些差异,但一般意思就是声明“这个东西不能改变”。之所以要禁止改变,可能是考虑到两方面的因素:设计或效率。下面将讨论final的三种应用场合:数据、方法及类。
1.数据
大家都这样用过:public static final int TRUE=1。这样定义出来变量是无法改变的,也是就说如果你使用类.TRUE=0,就会发生错误。
那么如果我用final修饰一个数组(引用类型)呢?此时final只是使得这个引用不能发生变化,但是引用的对象是可以变的,下面看一个实例:
public static final int[] ids = {1,2,3};
public static void main(String[] args){
System.out.println("befor changing:"+ids[1]);
ids[1]=123;
System.out.println("after changing"+ids[1]);
}
下面是输出结果,
befor changing:2
after changing123
虽然只是一个再简单不过的例子,但也给我们敲响警钟,在用final修饰的时候,如果是非基本类型,一定要注意啦!!!
2.方法
方法上需要用final,有两种情况:
1.出现在有继承的情况下,但是不希望子类对其进行修改,破坏它本来的含义。
2.程序执行的效率。用这个不一定会提高程序执行效率,在方法体较短时,会提高效率,但方法体较大时,就不一定了。
在一个类内的所有private方法都自动成为final,由于我们不能在类的外部访问一个private方法,所以它绝对不会被其他方法覆盖。你可以为private方法添加final提示符,但却不能为那个方法提供任何额外的含义。
3.类
如果说整个类都是final,就表明自己不希望从这个类继承。换言之,出于这样那样的原因,我们的类肯定不需要进行任何改变或者出于安全方面的理由,我们不希望有子类。
它内部的数据成员既可以是final,也可以不是,取决于我们具体选择。无论类是否被定义成final,应用于final的规则同样适用于数据成员。将类定义成final后,结果只是禁止进行继承——没有更多的限制。然而,由于它禁止了继承,所以一个final类中的所有方法都默认为final。因为此时再也无法覆盖它们。所以可以为final类内的方法添加final指示符,但却没有任何意义。
总结:
final在数据上的使用,我们需要注意的是这个数据是否真的被final了。
而对于方法和类的final却大部分都是出于自己的假定,例如假定自己的这个方法很需要执行效率,例如这个方法坚决不能有人改,例如这个类一定不能够被继承,否则……
但做出这样的假定一定要慎重,因为我们真的很难预测一个类以后会以什么样的形式再生或重复复用。常规用途的类尤其如此。若将一个方法定义成final,就可能在其他程序员的项目中对自己的类进行继承的途径,因为我们根本没有想到他会那样使用,我们的假定只是让他采用聚合。