final修饰符在java中经常使用,今天我就将使用final修饰符的点记录一下,一来给自己总结,二来也帮助需要的人
final首先是java中的一个关键字,能够修饰变量,方法以及类
当用final修饰一个类时,那么这个类是不能被继承的。这能够保护你的类,而且通常是由于安全原因而使用final修饰类。在java中,String类以及包装器类都是用final进行修饰的。
当final用在方法前,那么此方法将不能被覆盖(override),也就是说你不能在子类中覆盖这个方法的动作。这样子做也是为了保护此方法不被修改。
在使类成为final类或者使方法成为final方法之间是有折中的。因为如果类是final类,那么你就不能利用继承的优势,有时候更好的选择方式是使得不需要改变的方法成为final而不是使得整个类成为final类
实用final方法而不是final类的一个很好的例子是模板模式,在模板模式中模板方法概述了算法大致的运行方式,所以我们应该让模板方法为final方法,从而不让子类修改模板方法,但是同时我们也让子类可以修改模板方法中调用的其他抽象方法。final方法用在变量前意味着变量的值一旦分配之后就不能进行改变。不过对于指向数组或者集合的引用可能大家会有些疑惑。
用final修饰引用变量的真正意思是此引用变量不能指向其他的对象,但是此对象内部的状态是可以进行改变的。你能够往数组或者集合中添加,移除元素。
但是在Java中我们可以做到引用变量指向一个只读或者不可变的集合,常用的Colletions.unmodifiableCollection方法,通过将其中集合对应的修改元素的操作均抛出异常来阻止修改对应的集合。当static,final一起来修饰变量时,那么这个变量将会成为编译期常量。也就意味着static final变量将会被复制给引用这些变量的地方。这会造成一个问题,假设有一个static final变量在多个jar中共享,如果在其中一个jar中改变了这个共享的变量,那么其他的jar中的这个变量仍然是原来的值。
所以当你改变了一个public static final的变量,那么你要编译整个工程。一个not-static final变量如果在声明处没有给出定义,那么这个变量也是blank final变量。Java允许一个blank final变量,但是你一定要在所有的构造器中初始化它。如果你忘记杂所有的构造函数中初始化blank final变量,那么这个编译器将会抛出一个错误
在Java8中,除了lambda表达式,流 以及其他的一些变化,Java引入了一个新的概念叫做effectively final variable,这个变量的含义是允许在内部类或者lambda表达式使用一个非final的变量,则这个非final的变量就是effectively final variable。
在Java8以前的版本中,在内部类或者匿名内部类中是不允许使用非final修饰的局部变量的。但是在Java8中,你可以在内部类或者匿名内部类中使用effectively final变量,例如一个在分配过值之后它的值在也没有改变过的变量final修饰符可以作用于成员变量和局部变量(在方法中或者局部代码块中的变量)。
以上就是Java中的final修饰符,总的来说:如果用final修饰了引用变量,那么不能给这个引用变量重新分配值;如果用final修饰方法,那么不能覆盖这个方法;如果用final修饰类,那么不能继承这个类。