一、final变量
1.1 final成员变量
final修饰的成员变量必须由程序员显示地指定初始值
我们知道成员变量原本是可以不初始化的,默认会初始化,比如int类型的就初始化为0,引用类型初始化为null等,但是一旦用了final修饰就不是这样了,成员变量也必须要初始化才能使用。并且初始化的位置也是有所限制的。
类变量:必须在静态初始化块中初始化或者声明该类变量时初始化。不能在普通初始化块中初始化,因为类变量在类初始化阶段就已经初始化了,普通初始化块不能重新赋值。上述可以初始化的位置只能二选一。
实例变量:必须在非静态初始化块、声明该实例变量时或者构造函数中初始化。并且是三个地方只能选一个初始化。
1.2 final局部变量
final修饰局部变量时可以在定义时指定默认值,也可以在后面的代码中指定值,但是只能指定一次,不能重新赋值。
1.3 final修饰基本类型和引用类型的区别
final修饰基本类型:不能对基本类型重新赋值,也就是说,基本类型的值就是不变了的。
final修饰引用类型:同样不能对变量进行重新赋值,但由于是引用变量,效果是类似于C++中指针不能指向其他变量,而这个引用类型所指向的对象本身的值是可以改变的。
举例:final Person p = new Person(45);//假设传入了age为45
p.setAge(40);//这样做是合法的。
但是p=null;//这是非法的。
1.4 final变量的宏替换
宏替换:如果一个final变量满足条件被当作直接量,那么编译器会把程序中所有用到该变量的地方替换为宏。
条件有如下三个:
1.使用final修饰符修饰
2.定义变量时指定初始值
3.指定的初始值可以在编译时被确定
如final int a = 5;//就会被当作直接量
如final String str = “abd”+”def”;//这样也是直接量,字符串相加是可以得,但如果是str1+str2就不是了
二、final方法
2.1 final修饰的方法不能被重写
例子:
public class Father
{
public final void test(){}
}
class Sub extends Father
{
//将出现编译错误,final修饰的方法不能被重写
public void test(){}
}
2.2 final修饰的方法是可以被重载的
例子:
public class Father
{
public final void test(){}
//final修饰的方法被重载是没有问题的
public final void test(String str){}
}
2.3 final修饰private的方法
例子:
public class Father
{
private final void test(){}
}
class Son extends Father
{
//这么写是没有问题的,因为Son其实并没有继承到Father的test方法啊,所以这里就是定义了一个新的方法
public final void test(){}
}
定义为私有后用final修饰似乎没有什么意义,已经不能被继承了,那本来就不存在重写的情况吧
三、 final类
3.1 final修饰的类不可被继承
3.2 final类和不可变类是不同的概念,final类是不可被继承,而不可变类是指对象的成员变量都不能被修改。