Final
final
is a keyword that can be used with classes, methods, and variables.To declare a constant variable, use the
final
keyword. The value of afinal
variable cannot be changed once assigned.If a class is marked as
final,
it cannot be inherited by any other class.If a method is declared as
final,
it cannot be overridden in any subclass.Global
final
variables are initialized at the time of declaration, while localfinal
variables can be declared first and initialized later, but only once.
Syntax
final DataType variableName = value;
final ReturnType methodName(Parameters) {
// method body
}
final class ClassName {
// class body
}
Example
final class FinalClass {
final int finalVariable = 100;
final void finalMethod(final int param) {
System.out.println("Inside finalMethod");
System.out.println("Final variable value: " + finalVariable);
System.out.println("Final parameter value: " + param);
}
}
public class MasteringBackend {
public static void main(String[] args) {
FinalClass obj = new FinalClass();
obj.finalMethod(50);
}
}
In this example, we declare the class as final
, which means it cannot be inherited. We also make the variable final
, so its value cannot be changed. Also, the method is marked as final
, preventing it from being overridden in any subclass.
Output
Inside finalMethod
Final variable value: 100
Final parameter value: 50
Static
static
is a keyword that can be used to declare variables, methods, and nested classes.The
static
keyword is used for memory management. When a variable is declared asstatic,
only one copy of that variable is created, and it is shared among all instances of the class.
Example - If the name of a company is declared as
static
, such as Mastering Backend
, then all team members will reference the same company name. If the company name is rebranded, you only need to change it in one place, and it reflects everywhere.
Static members of the class are related to the class itself, so we access these directly using the class name.
A static block is automatically executed when the class is loaded.
Static members of the class cannot participate in inheritance.
Static members can be accessed directly from a static context.
Static members can also be accessed directly from a non-static context.
Syntax
static DataType variableName;
static ReturnType methodName(Parameters) {
// method body
}
static {
// static initialization code
}
class OuterClass {
static class NestedClass {
// class body
}
}
// Access the method and variable with class name
ClassName.staticVariable;
ClassName.staticMethod();
// Access the Inner class with outer class name
OuterClass.NestedClass nestedObj = new OuterClass.NestedClass();
nestedObj.methodName();
We can declare a method, a block, a variable, and even an inner class as static
.
Example
public class BankAccount {
private int accountNumber;
private double balance;
static double interestRate;
static int totalAccounts = 0;
static {
System.out.println("Bank system initialized.");
interestRate = 4.5;
}
public BankAccount(int accountNumber, double initialDeposit) {
this.accountNumber = accountNumber;
this.balance = initialDeposit;
totalAccounts++;
}
public void displayAccountDetails() {
System.out.println("Account No: " + accountNumber);
System.out.println("Balance: $" + balance);
System.out.println("Interest Rate: " + interestRate + "%");
}
public static void setInterestRate(double newRate) {
interestRate = newRate;
}
public static void showTotalAccounts() {
System.out.println("Total Bank Accounts: " + totalAccounts);
}
public static void main(String[] args) {
BankAccount acc1 = new BankAccount(101, 5000);
BankAccount acc2 = new BankAccount(102, 10000);
acc1.displayAccountDetails();
acc2.displayAccountDetails();
BankAccount.setInterestRate(5.0);
System.out.println("\nAfter updating interest rate:");
acc1.displayAccountDetails();
acc2.displayAccountDetails();
BankAccount.showTotalAccounts();
}
}
In this example, the static block is executed first because static blocks run as soon as the class is loaded into memory. The static
double interestRate
is shared across all accounts, which is why it is declared as static
. Similarly, static int totalAccounts
is used to keep track of the total number of accounts, and it is also marked as static.
To access these static
members, we do not need to create an object of the class. They can be called directly using the class name.
Bank system initialized.
Account No: 101
Balance: $5000.0
Interest Rate: 4.5%
Account No: 102
Balance: $10000.0
Interest Rate: 4.5%
After updating interest rate:
Account No: 101
Balance: $5000.0
Interest Rate: 5.0%
Account No: 102
Balance: $10000.0
Interest Rate: 5.0%
Total Bank Accounts: 2
this Keyword
this
is a keyword in Java.It is a reference variable that refers to the current object, the object whose method or constructor is being called.
It helps to resolve ambiguity between instance variables and parameters with the same name.
For example, if the instance variable and the parameter of a constructor or method share the same name,
this
is used to distinguish between them.
public class Student {
String name;
int age;
// Constructor
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public void displayInfo() {
System.out.println("Name: " + this.name); // Optional use
System.out.println("Age: " + this.age);
}
public static void main(String[] args) {
Student s1 = new Student("Ayush", 22);
s1.displayInfo();
}
}
In this example, name
and age
are the instance variables of the class, whereas name
and age
are also parameters of the constructor. That's why we use the this
keyword, which refers to the current object.
Output
Name: Ayush
Age: 22
this
keyword is used to invoke the current class method.
public class Student {
String name;
int age;
// Method to display student info
public void display() {
System.out.println("Name: " + name + ", Age: " + age);
}
// Method to invoke display using this keyword
public void showDetails() {
this.display(); // calling display() method using this
}
public static void main(String[] args) {
Student s2 = new Student("Ayush", 22); // Calls parameterized constructor
s2.showDetails(); // Calls display using this
}
}
Here, the showDetails()
method of the class is calling the display()
method with the help of the this
keyword. When we create the object of the class, the default constructor is called. Then, when we call the showDetails()
method, it triggers the display()
method because of the this
keyword.
Output
Name: Ayush, Age: 22
this()
this()
calling statement is used to call the current class constructor.this()
call must always be written inside a constructor.this()
statement must always be the first line inside the constructor.
Syntax
this();
this(parameter1.......);
In this example, the default constructor of the class is calling the parameterized constructor with the help of the this()
calling statement, passing the same number of parameters.
public class Student {
String name;
int age;
// Constructor 1: Default constructor
public Student() {
this("Unknown", 0);
System.out.println("Default constructor called");
}
// Constructor 2: Parameterized constructor
public Student(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Parameterized constructor called");
}
public static void main(String[] args) {
Student s1 = new Student(); // Calls default constructor
s1.showDetails(); // Calls display using this
}
}
Output
Parameterized constructor called
Default constructor called
with the help of the
this
keyword we can return the object of the current class.
public class Student {
String name;
int age;
// Method to set name
public Student setName(String name) {
this.name = name;
return this; // returns current object
}
// Method to set age
public Student setAge(int age) {
this.age = age;
return this; // returns current object
}
// Method to display student details
public void display() {
System.out.println("Name: " + name + ", Age: " + age);
}
public static void main(String[] args) {
Student student = new Student();
// Method chaining using 'this'
student.setName("Ayush").setAge(22).display();
}
}
Output
Name: Ayush, Age: 22
Constructor Chaining
Constructor chaining means calling one constructor from another constructor in the same class using the this()
keyword.
In this image, one constructor is calling the next constructor, creating a chain of constructor calls.
Example
public class Student {
String name;
int age;
String course;
String college;
// Constructor 1: No-arg constructor
public Student() {
this("Ayush"); // Calls Constructor 2
System.out.println("Constructor 1: No-arg constructor");
}
// Constructor 2: One-arg constructor
public Student(String name) {
this(name, 22); // Calls Constructor 3
System.out.println("Constructor 2: Name = " + name);
}
// Constructor 3: Two-arg constructor
public Student(String name, int age) {
this(name, age, "Computer Science"); // Calls Constructor 4
System.out.println("Constructor 3: Name = " + name + ", Age = " + age);
}
// Constructor 4: Three-arg constructor
public Student(String name, int age, String course) {
this.name = name;
this.age = age;
this.course = course;
this.college = "XYZ University";
System.out.println("Constructor 4: Name = " + name + ", Age = " + age + ", Course = " + course + ", College = " + college);
}
public static void main(String[] args) {
Student s = new Student(); // Starts constructor chain
}
}
In this example, when we create an object of the Student class using Student s = new Student();
, the constructor chain starts from the no-argument constructor. Inside this constructor, the line this("Ayush");
is executed, which calls the one-argument constructor public Student(String name)
.
Inside the one-argument constructor, the line this(name, 22);
is executed, which calls the two-argument constructor public Student(String name, int age)
.
Next, inside the two-argument constructor, the line this(name, age, "Computer Science");
is executed, which calls the three-argument constructor public Student(String name, int age, String course)
.
Finally, the three-argument constructor initializes all the instance variables and prints the final message.
After the deepest constructor completes its execution, control returns back up the chain, and each constructor prints its message in reverse order of the call stack.
Output
Constructor 4: Name = Ayush, Age = 22, Course = Computer Science, College = XYZ University
Constructor 3: Name = Ayush, Age = 22
Constructor 2: Name = Ayush
Constructor 1: No-arg constructor
Super Keyword
super
is a reference variable that is similar to thethis
keyword, but it is used to refer to the immediate parent class object.When an instance of a subclass is created, an instance of its parent class is also created implicitly, which which is referred by
super
reference variable.The
super
keyword is used to call the immediate parent class's instance variables.It is also used to invoke the parent class's methods in subclasses.
Syntax
super.methodName();
Example
class Parent {
void show() {
System.out.println("This is Parent class method");
}
}
class Child extends Parent {
void show() {
System.out.println("This is Child class method");
}
void display() {
super.show(); // Calls Parent class show()
show(); // Calls Child class show()
}
}
public class Main {
public static void main(String[] args) {
Child obj = new Child();
obj.display();
}
}
In this example, we are calling the superclass method show()
from within the child class. When we create an object of the subclass, the superclass object is implicitly created as well. So, when we call the subclass method display()
, the line super.show();
is executed, which calls the parent class method.
Output
This is Parent class method
This is Child class method
super
keyword is used to invoke the immediate parent class's variables from within the subclass.
Syntax
super.variableName;
Example
class Parent {
int x = 100;
}
class Child extends Parent {
int x = 200;
void display() {
System.out.println("Child x: " + x); // refers to Child's x
System.out.println("Parent x: " + super.x); // refers to Parent's x
}
}
public class Main {
public static void main(String[] args) {
Child obj = new Child();
obj.display();
}
}
In this example, we are calling the superclass variable x
in the subclass. When we create the object of the subclass, the superclass object is implicitly created. So, when we access the variable x
from the subclass, the line x = 100
is executed, and the parent class variable is accessed, resulting in the expected output.
Output
Child x: 200
Parent x: 100
super()
super()
calling statement is similar tothis()
, butsuper()
is used to call the immediate parent class constructor.Like the
this
keyword, it is used inside the constructor.super()
statement must always be written as the first line in the constructor.
Syntax
super(); // Calls the no-argument constructor of the parent class
super(arguments); // Calls the parameterized constructor of the parent class
Example
class Parent {
Parent() {
System.out.println("Parent class constructor");
}
}
class Child extends Parent {
Child() {
super(); // Optional here as it is called implicitly
System.out.println("Child class constructor");
}
}
public class Main {
public static void main(String[] args) {
Child obj = new Child();
}
}
In this example when we create the object of child class, the parent class constructor is implicitly called.
Output
Parent class constructor
Child class constructor
Example
class Parent {
Parent(String name) {
System.out.println("Parent class constructor with name: " + name);
}
}
class Child extends Parent {
Child() {
super("Ayush"); // Calls Parent constructor with argument
System.out.println("Child class constructor");
}
}
public class Main {
public static void main(String[] args) {
Child obj = new Child();
}
}
In this example, when we create an object of the subclass, the superclass object is implicitly created, which in turn invokes the superclass methods. Here, we are specifically invoking the parameterized constructor of the superclass from the subclass using the super()
calling statement.
Output
Parent class constructor with name: Ayush
Child class constructor
Constructor chaining means calling one constructor from another. When using super()
, it chains constructors from subclass to superclass.
Example
class Parent {
Parent() {
System.out.println("Parent constructor");
}
}
class Child extends Parent {
Child() {
super(); // Calls Parent constructor (constructor chaining)
System.out.println("Child constructor");
}
}
public class Main {
public static void main(String[] args) {
new Child();
}
}
Here in this example Parent-to-child constructor chaining is present.
Output
Parent constructor
Child constructor