final意思为“最终的”,所以final修饰符修饰的类、方法、变量不可改变。下面会从各个方面解析final修饰的类、方法、变量的规律。
1.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);
}
}
2.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;
}
}
3.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