final修饰的成员变量是不可改变量,必须由程序员显示地指定初始值
修饰成员变量
类变量:必须在静态初始化块中指定初始值或者声明该类变量时指定初始值,而且只能在两个地方的其中之一指定.
实例变量:必须在非静态初始化,声明该实例或者构造器中指定初始值,而且只能在三个地方的其中之一
1.需要注意的是,如果普通初始化块已经为某个实例变量指定了初始值,那么不能在构造器中再为该实例变量指定初始值
2.final修饰类变量要么在声明时,要么在静态初始化块中为该类变量指定初始值.
3.实例变量不能在静态块中进行初始化操作,类变量也不能在普通初始化块中指定初始值,因为类变量在类初始化阶段已经被初始化了,普通初始化块不能对其重新赋值
各种情况示例代码如下:
package com.j1803.finalTest;
public class FinalVariableTest {
//定义成员变量时指定默认值,合法
final int a=6;
final static int b=78;
//下面变量将在构造器或者初始化块中分配初始值
final int c;
final int d;
final static int e;
final static int f;
final int g;
//1,普通初始化块
{
//在普通初始化块中为实例变量指定初始值
c=12;
//不能给a重新赋值,下列语句非法
//a=45;
//不能给静态类变量赋值
//e=45;
}
//2.静态初始化块
static{
//不能给实例变量赋值
//d=45;
e=12;
//不能对b重新赋值
//b=45;
f=789;
}
//使用构造器对实例变量d赋值
//如果在初始化块中已经对d进行了赋值,则构造器中不能对final变量重新赋值,
public FinalVariableTest(int num){
//c=45;
d=12;
g=num;
}
public void changeFinal(){
//普通方法不能给final修饰的成员变量赋值
//this.g=45;
}
//定义成员变量时指定默认值,合法
final int a=6;
final static int b=78;
//下面变量将在构造器或者初始化块中分配初始值
final int c;
final int d;
final static int e;
final static int f;
final int g;
//1,普通初始化块
{
//在普通初始化块中为实例变量指定初始值
c=12;
//不能给a重新赋值,下列语句非法
//a=45;
//不能给静态类变量赋值
//e=45;
}
//2.静态初始化块
static{
//不能给实例变量赋值
//d=45;
e=12;
//不能对b重新赋值
//b=45;
f=789;
}
//使用构造器对实例变量d赋值
//如果在初始化块中已经对d进行了赋值,则构造器中不能对final变量重新赋值,
public FinalVariableTest(int num){
//c=45;
d=12;
g=num;
}
public void changeFinal(){
//普通方法不能给final修饰的成员变量赋值
//this.g=45;
}
public static void main(String[] args) {
FinalVariableTest test=new FinalVariableTest(45);
System.out.println("a:"+test.a);
System.out.println("b:"+FinalVariableTest.b);
System.out.println("c:"+test.c);
System.out.println("d:"+test.d);
System.out.println("e:"+FinalVariableTest.e);
System.out.println("f:"+FinalVariableTest.f);
System.out.println("g:"+test.g);
//answer
/*a:6
b:78
c:12
d:12
e:12
f:789
g:45*/
FinalVariableTest test=new FinalVariableTest(45);
System.out.println("a:"+test.a);
System.out.println("b:"+FinalVariableTest.b);
System.out.println("c:"+test.c);
System.out.println("d:"+test.d);
System.out.println("e:"+FinalVariableTest.e);
System.out.println("f:"+FinalVariableTest.f);
System.out.println("g:"+test.g);
//answer
/*a:6
b:78
c:12
d:12
e:12
f:789
g:45*/
}
}
如果打算在构造器中,或者初始化块中,对final成员变量进行初始化,则不要在初始化之前直接访问final成员变量,但Java又允许通过方法来访问final成员变量,此时会看到系统将final成员变量默认初始化为0,(或者U0000,false,null)
package com.j1803.finalTest;
public class FinalVariableTest2 {
final int age;
{
//下面一行代码直接报错
//System.out.println(age);
showAge(this.age);
age=12;
System.out.println(age);
}
public void showAge(int age){
System.out.println("age===="+age);
}
final int age;
{
//下面一行代码直接报错
//System.out.println(age);
showAge(this.age);
age=12;
System.out.println(age);
}
public void showAge(int age){
System.out.println("age===="+age);
}
public static void main(String[] args) {
FinalVariableTest2 test=new FinalVariableTest2();
}
FinalVariableTest2 test=new FinalVariableTest2();
}
}
answer:
age====0
12
12
final修饰的成员变量在显示初始化之前不能直接访问,但可以通过方法来访问,基本可以断定是java设计的一个缺陷