关于final关键字,大家都蛮熟悉的了,这次我来讲一下我对final的理解。
final是用来修饰成员变量的一个关键字,被他修饰的成员变量在赋值之后就不能再重新赋值,因此被修饰的成员变量要显式地为其赋值,系统不会为final变量设置默认初始值,因为这样final关键字就没有意义了。
成员变量按照所有者可以分为类变量(静态变量)和实例变量两种,因此我们要从两种情况来分析final的使用。在类变量中,只能在静态初始化块或声明变量时赋初值;而实例变量可以在非静态初始化块、声明变量时或构造器中赋初值。我们来看一段代码:
public class finalTest {
final int a = 1;
final int b;
final String c;
final static String d;
//在初始化块里赋初值
{
b = 11;
}
//在静态初始化块里赋初值
static {
d = "aaa";
}
//在构造器里赋初值
public finalTest() {
c = "ccc";
}
}
这里我们可以看到只要符合条件,可以在两种情况里所列出的地方来给final变量赋初值。
用于局部变量和方法形参
在局部变量和方法形参里都能用final关键字来修饰变量,在修饰局部变量时,可以在申明变量或者之后再赋初值;而用于方法形参中则表示方法里不能再更改传进来的参数了,可以防止一些不必要的错误。在刚才的类里面加上如下代码:
//如果在方法里面给x赋值就会报错
public void xxx(final int x) {
final int aa = 10;
final int bb;
bb = 5;
System.out.println(x + aa + bb);
}
public static void main(String[] args) {
finalTest test = new finalTest();
test.xxx(10);
}
用于引用类型变量
final在修饰基本类型变量时,一旦给基本类型变量赋值后就不能再更改。但在修饰引用类型变量时只保证引用对象的地址不变,对象是可以改变的,即比如你引用了一个人的对象,这个人是不能变的,但他的体重、年龄等属性是可以改变的。照例上代码:
class Person {
private String name;
public Person(String name) {
this.name = name;
System.out.println("我叫:" + name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class XXXtest {
public static void main(String[] args) {
final Person a = new Person("小明");
a.setName("中明");
System.out.println(a.getName());
// a = null; 这里更改引用的对象,因此会报错
}
}
这里a是引用了Person类的、用final修饰的对象,因此我们不能再改变这个对象的引用,但里面的一些属性是可以作出修改的。
final修饰方法和类
final修饰的方法不能被子类重写,但可以重载。你能够在子类写一个和父类被final修饰的方法一样的方法,但这个方法与父类的那个方法并没有关系。
当你不想要你的类有子类的时候,你可以用final来修饰这个类。
参照:https://blog.youkuaiyun.com/cadi2011/article/details/51615514