Java面向对象——final修饰符
final意思为“最终的”,所以final修饰符修饰的类、方法、变量不可改变。下面会从各个方面解析final修饰的类、方法、变量的规律。
final修饰成员变量
1.1成员变量
成员变量是随类的初始化或对象初始化时就会初始化的。类初始化时系统会为类变量分配内存、默认值;创建对象时系统会为该对象的实例变量分配内存、默认值。
1.2 final修饰的成员变量
final修饰的成员变量必须在程序中显式指定初始值。
final修饰的类变量必须在①静态初始化块中 或 ②声明该类变量时指定初始值;
final修饰的实例变量必须在①非静态初始化块中、②声明该实例变量时或③构造器中指定初始值。
1.3示例代码
代码如下:
public class Final_Variable {
//final修饰 实例变量 声明时赋初值 正确
final int number = 1;
//final修饰 实例变量 非静态初始化块赋初始值 正确
final String name;
//非静态初始化块
{
name = "java";
//final修饰的number变量已经赋值,不可改变,下面一行代码错误
//number = 2;
}
//final修饰 实例变量 构造器中赋初值 正确
final int n;
//构造器
public Final_Variable() {
n = 1024;
}
//final修饰 类变量 声明时赋初值 正确
final static int a = 3;
//final修饰 类变量 静态代码块中赋初值 正确
final static int b;
//静态代码块
static {
b = 2019;
}
public static void main(String[] args) {
Final_Variable test = new Final_Variable();
//值不变
System.out.println(test.n);
System.out.println(test.name);
System.out.println(test.number);
System.out.println(test.a);
System.out.println(test.b);
}
}
final修饰局部变量
因为系统不会对局部变量进行初始化,所以局部变量必须由程序进行显式初始化;对局部变量进行初始化,可以在①定义时指定默认值,那么之后就不能赋值;也可以②不指定默认值,之后只能赋值一次。
示例代码如下:
public class Final_Variable {
public void test(final int a) {
//对形参用final修饰时,在代码中无法赋值,下面的语句错误
//a = 1;
}
public static void main(String[] args) {
final int a;
//在声明变量a时没有赋值,那么之后可以赋值一次
a = 1;
//下面语句错误,无法继续赋值
//a = 2;
}
}
final变量的宏替换
如果被赋值的表达式只是基本的算术表达式或字符串连接运算,没有访问其他的变量、方法,那么java编译器会将这些变量当做“宏变量”处理,会进行宏替换。
示例代码如下:
public class FinalReplace {
public static void main(String[] args) {
//使用final修饰,编译时会宏替换为“studyjava”
final String example = "study" + "java";
String a = "studyjava";
//因为java的存储池中不会有两个相同的变量,所以地址相同,输出为true
System.out.println(example == a);
String c = "study";
String d = "java";
//没有final修饰,调用其他的变量运算时,e的结果是由c、d两个变量构成了,存储地址未知
String e = c + d;
//此时输出时为true
System.out.println(a == e);
}
}
输出结果为:
true
false
final方法
1.1 final方法的使用
在前面的继承中我们说过,子类可以通过继承方式,破坏父类中的封装方法;那么如果我们的封装方法不想被子类重写,我们就可以使用final修饰符修饰用于封装的方法,这样的话,用于封装的方法就不能被子类进行重写了,保证了封装不会被破坏。
1.2 final方法的重载
虽然被final修饰的方法无法被重写,但是可以进行重载。
区别点
重载方法
重写方法
参数列表
必须修改
一定不能修改
返回类型
可以修改
一定不能修改
异常
可以修改
可以减少或删除,一定不能抛出新的或者更广的异常
访问
可以修改
一定不能做更严格的限制(可以降低限制)
1.3代码示例
class Father{
public final void test() {}
}
public class Finalidea {
//想重写父类final修饰的test方法则会出现错误
public void test() {}
public final void test() {}
//重载test方法则没有问题
public final void test(int a) {}
}
final类
当你需要你的类不能有子类不想被继承时,可以使用final修饰符修饰这个类。