It does not need to be initialized at the point of declaration: this is called a "blank final" variable.
A blank final instance variable of a class must be definitely assigned in every constructor of the class in which it is declared;
similarly, a blank final static variable must be definitely assigned in a static initializer of the class in which it is declared; otherwise, a compile-time error occurs in both cases.
Final and inner classes[edit]
When an anonymous inner class is defined within the body of a method, all variables declared
final
in the scope of that method are accessible from within the inner class.
For scalar values, once it has been assigned, the value of the
final
variable cannot change. For object values, the reference cannot change. This allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. Once the outer method has terminated and its stack frame has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory.
In the following example.
The JVM copies the value of the final variable and stores it as a constant in the Constant Pool as
#16 = Float 3.2f
//--------------------Java---------------------------
public class House {
static final int AGE_OF_THE_HOUSE;
static{
AGE_OF_THE_HOUSE = 50;
}
final int colorOfTheWall;
public House() {
colorOfTheWall = 0x2032;
}
static String paint(String message){
final float width = 3.2f;
class SmallRoom{
float length = 3.5f;
float roomSize = length * width;
}
return "Paint \"" + message + "\" on the wall.";
}
}
-------------------Bytecode-----------------
class House$1SmallRoom
SourceFile: "House.java"
EnclosingMethod: #26.#28 // House.paint
InnerClasses:
#32= #1; //SmallRoom=class House$1SmallRoom
minor version: 0
major version: 50
flags: ACC_SUPER
Constant pool:
#1 = Class #2 // House$1SmallRoom
#2 = Utf8 House$1SmallRoom
#3 = Class #4 // java/lang/Object
#4 = Utf8 java/lang/Object
#5 = Utf8 length
#6 = Utf8 F
#7 = Utf8 roomSize
#8 = Utf8 <init>
#9 = Utf8 ()V
#10 = Utf8 Code
#11 = Methodref #3.#12 // java/lang/Object."<init>":()V
#12 = NameAndType #8:#9 // "<init>":()V
#13 = Float 3.5f
#14 = Fieldref #1.#15 // House$1SmallRoom.length:F
#15 = NameAndType #5:#6 // length:F
#16 = Float 3.2f
#17 = Fieldref #1.#18 // House$1SmallRoom.roomSize:F
#18 = NameAndType #7:#6 // roomSize:F
#19 = Utf8 LineNumberTable
#20 = Utf8 LocalVariableTable
#21 = Utf8 this
#22 = Utf8 LHouse$1SmallRoom;
#23 = Utf8 SourceFile
#24 = Utf8 House.java
#25 = Utf8 EnclosingMethod
#26 = Class #27 // House
#27 = Utf8 House
#28 = NameAndType #29:#30 // paint:(Ljava/lang/String;)Ljava/lang/String;
#29 = Utf8 paint
#30 = Utf8 (Ljava/lang/String;)Ljava/lang/String;
#31 = Utf8 InnerClasses
#32 = Utf8 SmallRoom
{
float length;
flags:
float roomSize;
flags:
House$1SmallRoom();
flags:
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: invokespecial #11 // Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #13 // float 3.5f
7: putfield #14 // Field length:F
10: aload_0
11: aload_0
12: getfield #14 // Field length:F
15: ldc #16 // float 3.2f
17: fmul
18: putfield #17 // Field roomSize:F
21: return
LineNumberTable:
line 19: 0
line 20: 4
line 21: 10
line 19: 21
LocalVariableTable:
Start Length Slot Name Signature
0 22 0 this LHouse$1SmallRoom;
}
No comments:
Post a Comment