Tuesday, May 5, 2015

final Keyword in Java

final variable can only be initialized once.

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 thefinal 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