Final keyword in Java

final methodfinal class

In the previous blog we learned about the types of inheritance, and access modifiers in Java. If you want to know more about it then visit Types of Inheritance in Java. In this blog, we will go through the final keyword in Java. final keyword in Java is used to limit the user. It can be used with multiple contexts i.e. we can use final with variables, methods, and class. Let's go through it in detail.

Final Method and Class

Suppose if we want to prevent someone from forming a subclass or child class of one of our classes then we use the final keyword. The class can also use a final keyword which means the class is a final class. Final Classes are nothing but classes that cannot be extended. In order to indicate the class as final we write the final keyword in the definition of that class. For example, if we have a class as AtrowelExecutive and we want to prevent others from subclassing the AtrowelExecutive class, then we just have to write the final modifiers while declaring a class.

Syntax

public final class AtrowelExecutive extends AtrowelManager{
. . .
}

We can also make a particular method as final in a class. If we make a method final then no subclass can override that particular method. Note that all the methods in a final class will be automatically final. For example

e.g.

public class AtrowelEmployee{
  . . .
  public final String getName(){
    return name;
  }
  . . .
}

The reason behind making a method or class final is to make sure that the signature cannot be changed by its child class or subclass. For example, the String class is final which means that no one can define a subclass of String. For example, if we create a String reference, we know it will refer to a String.

Earlier, some programmers used the final keyword to avoid the overhead of dynamic binding. If a method is short and is not overridden, then a compiler can optimize the method call away. This process is called inlining. Let me give you an example if there is a method getName(), then rather than inlining a call atrowelObj.getName, it replaces with the field access i.e. atrowelObj.name. But if the getName() is overridden in another class, then it will be difficult for compiler to inline because the compiler will not have idea of what the overriding code is doing. Luckily the Just in Time(JIT) compiler can do better job than the traditional compiler. Because, it knows which classes extend a given class, and it can check whether any class actually overrides a given method. If the method is called frequently, is short and not overridden , then the JIT compiler can inline it.

Example of Final method

class AtrowelFinalMethodEx{
  final void run(){
    System.out.println("In the run() method of AtrowelFinalMethodEx class");
  }
}
class AtrowelFinal extends AtrowelFinalMethodEx{
  void run(){
    System.out.println("In the run method of AtrowelFinal class");
  }
  public static void main(String args[]){
    AtrowelFinal atrowelObj= new AtrowelFinal();
    atrowelObj.run();
  }
}

Output

Compile Time Error: overridden method is final

In the above example we have two classes: Class AtrowelFinalMethodEx and class AtrowelFinal. In the class AtrowelFinalMethodEx we have defined a method that is declared as final and the same method is overridden in the child class i.e. AtrowelFinal. As we have already seen, the final method cannot be overridden, so the compiler has given a compile time error saying the overridden method is final.

We can also create anonymous arrays. Anonymous arrays are arrays that can be created .

Example of Final class

final class AtrowelFinalClassEx{}
class AtrowelFinal extends AtrowelFinalClassEx{
  void run(){
    System.out.println("Inside the run() of class AtrowelFinalClassEx");
  }
  public static void main(String args[]){
    AtrowelFinal atrowelObj= new AtrowelFinal();
    atrowelObj.run();
  }
}

Output

cannot inherit from final AtrowelFinalClassEx

As we cannot extend the final declared as final, so we the compiler has given a compile time error saying cannot inherit from final AtrowelFinalClassEx.


Final Variables

Final variables are the variables whose values cannot be changed. If we make a variable as final, then the value of that variable will not be changed. It will remain constant. We will see it with the help of an example

e.g.

class AtrowelFinalVariableEx{
  final String atrowelString="Javashortkicks";
  void run(){
    atrowelString="Javakicks";
  }
  public static void main(String args[]){
    AtrowelFinalVariableEx atrowelObj=new  AtrowelFinalVariableEx();
    atrowelObj.run();
  }
}

Output

cannot assign a value to final variable atrowelString atrowelString="Javakicks";

In the above example we are trying to modify the value of the variable which is declared as final, due which the compiler is giving error saying cannot assign a value to final variable atrowelString atrowel = “Javakicks”.


Type Casting in Java

Type Casting in Java is nothing but converting the value of one primitive data type into another. If the value of one data type is assigned to another, then we must be aware of the compatibility of the data type. Java can perform the conversion automatically if the data types are compatible, this process is known as Widening Casting or Implicit Casting and if not, then datatypes need to be cast or converted explicitly which is known as Narrowing Casting. Following are the types of casting in Java

  1. Widening Casting
  2. Narrowing Casting
  1. Widening Casting
  2. The process in which one data type is converted into another data type automatically by Java, then this process is called Widening Type Casting. It is also called Implicit Casting. In Widening Casting lower data type is converted into higher data type. Widening Type Casting takes place under two conditions.

    • Compatibility of Datatype - Let me explain it with the example, if we take the example of numeric data types, numeric data types are compatible only with numeric data types like converting int to double, but the numeric data types are not compatible with other data types like boolean, char, etc, just like String is not compatible with a boolean.
    • If the value of the data type to be converted has a smaller length i.e. 4 bytes to the larger data type i.e. 8 bytes.

    Widening Type Casting follows the order as

    byte  ->  short  ->  char  ->  int  ->  long  ->  float  ->  double

    e.g.

    class AtrowelWideningCastingEx {
      public static void main(String[] args) {
        int atrowelNum = 9;
        System.out.println("The value of atrowelNum: " + atrowelNum);
        double atrowelData = atrowelNum;
        System.out.println("The value of atrowelData: " + atrowelData);
      }
    }

    Output

    The value of atrowelNum: 9
    The value of atrowelData: 9.0
  3. Narrowing Casting
  4. The process of converting the value of a larger data type into a smaller data type is called Narrowing Casting. It is also known as Explicit Type Casting. This casting is done manually as we have to do casting using the () operator. If we fail to do casting, then the compile error will be thrown by the compiler. Narrowing Type Casting follows the order as:

    double  ->  float  ->  long  ->  int  ->  char  ->  short  ->  byte

    e.g.

    class AtrowelNorrowingCastingEx {
      public static void main(String[] args) {
        double atrowelNum = 99.10;
        System.out.println("The value of atrowelNum : " + atrowelNum);
        int atrowelData = (int)atrowelNum;
        System.out.println("The value of atrowelData: " + atrowelData);
      }
    }

    Output

    The value of atrowelNum : 99.1
    The value of atrowelData: 99

Core Java Tutorial

Get in Touch

Atrowel will be pleased to receive your feedback and suggestions. Those of you who would like to contribute, please send us an email.