Final Modifier Simplified in Java





Final Modifier in Java:
final is a modifier in Java. The meaning changes from context to context. The final modifier can be used before a class, method, argument, blank field or variable. And its definition changes for each of them. It is available for the below reasons:

  1. Efficiency
  2. Design
  3. Optimization

A filed can be of both static and final. It means that it has only one piece of storage that can not be changed. Final variables act like a class variable and they do not take any space on individual objects of the class.
Impact of the final keyword on the variable:
If final is used before a variable, then the value of that variable will act as a constant and thus, cannot be changed. A final data is a constant in java. Using final keyword the code convey the message to the compiler that

  1. It may be a compile-time constant that can not be changed.
  2. It may be a value initialized at runtime that we do not want to change.
In case of compile-time constant, the compiler may fold the constant value to any of the calculation where it is used. That means the calculation may be performed during compile time instead of run time which eliminates the overhead during runtime.
The constant must be primitive and are expressed using the final keyword. A value must be given at the time of definition of such constant.
Below is the example of compile-time constant:

final int PIE=3.14;
final double BONUS=.56;
Below is the example of the runtime constant:

final int SLEEPVALUE=(int)(Math.random()*60);
 

abstract class Shape{
    final static int SIZE=20;
    public void display()
    {
        System.out.println("Display method of Shape");
    }
    }

public class Rectangle extends Shape{

     public static void main(String []args){
         Rectangle obj=new Rectangle();
         obj.display();
        // obj.SIZE=30;
        System.out.println(SIZE);
        
     }
     
}
 
The output of the code:
$javac Rectangle.java
$java -Xmx128M -Xms16M Rectangle
Display method of Shape
20
Now if we omit the lines of the redefinition of SIZE

abstract class Shape{
    final static int SIZE=20;
    public void display()
    {
        System.out.println("Display method of Shape");
    }
    }

public class Rectangle extends Shape{

     public static void main(String []args){
         Rectangle obj=new Rectangle();
         obj.display();
        obj.SIZE=30;
        System.out.println(SIZE);
        
     }
     
}
 
The output of the code:
$javac Rectangle.java
Rectangle.java:14: error: cannot assign a value to final variable SIZE
obj.SIZE=30;
       ^
1 error

Impact of the final keyword on the Class:
If the final is used before a class, then that class cannot be sub-classed. we generally do not use final class but for security reason sometimes, we create the class as final. So nobody can subclass it and can change the methods of how they work. Like-String class. So we can not inherit the class.putting an entire class is final means that we don't want to inherit from this class or allow anyone else to do so. This is done if the class does not need any change.Defining the class as final simply prevents inheritance.So in other words final prevents a class being further sub classes for security reason.Any such attempt will cause compile time error.

class abc{}
final class xyz{
int i=10;
int j=20;
abc x=new abc();
void mno()
{
}
}
// not possible as xyz class is final class
class AnyClass extends xyz{}
public class MyClass{
public static void main(String args[])
{
xyz newClass=new xyz();
newClass.mno();
newClass.i=40;
newClass.j=60;
}
}
 
Impact of the final keyword on the Methods:
If the final is used before a method, then that method cannot be overridden. In this case, nobody can redefine the method. like-println().The same rule applies to final data members irrespective of the class is defined as final. Making a method final serves two important purposes.. they are as follows:

  1. It simply put a lock on the method to prevent any inheriting class from changing its meaning. Mostly we use this as design phase.It implies that the behavior of the method is retained.In other words,final methods are not overridden. Any private method of a class is implicitly final as we can not access a private method,hence they can not be overridden. However adding final modifier to a private method does not make sense as both they do the same thing.
  2.  The second reason is efficiency. It allows the compiler to turn any method call to in line calls. (when the compiler sees method call mechanism that is to push arguments on the stack,hop over the to the method code,execute it,hop back ,clean off the stack arguments and deal with the return values,it simply replaces the method call with a copy of the method code that reduces the execution overhead and increases efficiency.However if the method body is too big , this mechanism may not hold good and may not give improvement)

Defining the class as final simply prevents inheritance.This means that all methods in a final class are implicitly final.(There is no way to override them).

Impact of final on method argument:
Java allows us to make arguments final by declaring them as such in the argument list. Final argument means inside the method , we can not change what the argument handle points to.

class MyClass{
public void doSomething(){}
}
public class FinalArgumentTest{
void withFinal(final MyClass mc)
{
//mc=new MyClass();//not possible as mc is final
mc.doSomething();
}
void withoutFinal(MyClass mc)
{
mc=new MyClass();//possible as mc is not final
mc.doSomething();
}
public static void main(String args[])
{
FinalArgumentTest fat=new FinalArgumentTest();
fat.withFinal(null);
fat.withoutFinal(null);
}
}
 
We can pass or assign a null handle to an argument without compilation issue for final and non final arguments.
Impact of final on fields:
Java allows us to create final blank fields. They are not given any initialization values but we need to initialize them before we use them.Blank fields provides flexibility like a final filed inside a class can now be different for each object and yet still retains its immutable quality.

public class BlankFinalTest{
final int i=0; //initialized final
final int j; //blank final
final MyClass mc; //blank final handle
//blank final must be initialized in the constructor
BlankFinalTest()
{
    j=1; //initialized the blank field
    mc=new MyClass();
}
BlankFinalTest(int x)
{
    j=x; //initialized the blank field
     mc=new MyClass();
}
     public static void main(String []args){
        BlankFinalTest bft=new BlankFinalTest();
        
     }
     
}
class MyClass{}
 
The assignment to final either with an expression at the point of definition of the field or in every constructor.
Impact of final on objects:
When using final with object handles rather than primitives,the final makes the value constant but with an object handle,final makes the handle constant.The handle must be initialized to an object at the point of decleration and handle can never changed to any other object.

final object; //handle constant needs to be initialized.
 
Compiler has the same efficiency when we make a class or method final. But as a coder we don't know when and how the final class and method will be used. We have to be very careful before making any class or method as final. Specially for general purpose reusable class and methods.
Final Modifier Simplified in Java Final Modifier Simplified in Java Reviewed by Devopriya on June 23, 2012 Rating: 5

No comments:

Powered by Blogger.