Java SE: static modifier

Java Fundamentals

javase
static
What is the static modifier in Java
Author

albertprofe

Published

Tuesday, June 1, 2021

Modified

Tuesday, February 20, 2024

📘 static modifier

In Java, the static modifier is used to indicate that a class or class member belongs to the class itself, rather than to an instance of the class.

In other words, the static modifier indicates that the class or class member is associated with the class as a whole, rather than with a specific instance of the class.


1 static modifier

Classical use and basic example of static method, we call within the class our static method just using the name of the method printArea():

Two static methods with parameters. Parameters are the variables we use in the method definition whereas arguments are the values we pass in the method call. These two terms are often used interchangeably

Two static methods with parameters. Parameters are the variables we use in the method definition whereas arguments are the values we pass in the method call. These two terms are often used interchangeably

The static modifier has several different uses in Java, depending on where it is applied. Here are some examples of how the static modifier can be used in Java.

1.1 static code block

In Java, we have a special block known as aStatic Initialization Block. A Static Initialization Block is executed before the main() method, it will execute once. This block will not return anything and we can not use the this keyword since it does not have any instance.

For example:

MovieManager.java
static {            
    int count = 0;
    String name ="Alien";
    double priceMovie = 45.50;
};

1.2 static field

When applied to a field, the static modifier indicates that the field belongs to the class itself, rather than to an instance of the class. This means that all instances of the class share the same value for the static field.

For example:

Counter.java
public class Counter {
    // Static field
    private static int count = 0;

    // Constructor
    public Counter() {
        count++;
    }

    // Getter method for the count field
    public static int getCount() {
        return count;
    }
}

In this example, the count field is marked as static, which means that all instances of the Counter class share the same value for the count field. When a new instance of the Counter class is created, the count field is incremented, and the new value is shared by all instances of the class.

Another example:

Account.java
public class Account {
    // Static field
    private static int nextAccountNumber = 1;

    // Private instance variables
    private int accountNumber;
    private String name;
    private double balance;

    // Constructor
    public Account(String name, double balance) {
        this.accountNumber = nextAccountNumber++;
        this.name = name;
        this.balance = balance;
    }

    // Getter method for the accountNumber field
    public int getAccountNumber() {
        return accountNumber;
    }

    // Getter method for the name field
    public String getName() {
        return name;
    }

    // Getter method for the balance field
    public double getBalance() {
        return balance;
    }

    // Method for depositing money into the account
    public void deposit(double amount) {
        balance += amount;
    }

    // Method for withdrawing money from the account
    public void withdraw(double amount) {
        balance -= amount;
    }
}

In this example, the Account class defines a nextAccountNumber field that is marked as static. This means that the nextAccountNumber field belongs to the Account class itself, rather than to an instance of the Account class. This means that all instances of the Account class share the same value for the nextAccountNumber field.

When a new instance of the Account class is created, the nextAccountNumber field is incremented, and the new value is shared by all instances of the class. This allows each instance of the Account class to have a unique accountNumber field, which is generated automatically using the nextAccountNumber field.

1.3 static method

When applied to a method, the static modifier indicates that the method belongs to the class itself, rather than to an instance of the class. This means that the static method can be called on the class itself, rather than on an instance of the class.

For example:

MathUtils.java
public class MathUtils {
    // Static method
    public static double squareRoot(double number) {
        return Math.sqrt(number);
    }
}

In this example, the squareRoot() method is marked as static, which means that it can be called on the MathUtils class itself, rather than on an instance of the MathUtils class. This allows the squareRoot() method to be called without creating an instance of the MathUtils class, which can be useful in some situations.

For example:

MovieManager.java
public class MovieManager {

    // Static method
    public static boolean createMovie(Movie movie) {
        boolean result = false;
        // to-do algorithmic to solve this method
        return result;
    }

    // Static method
    public static boolean deleteMovie(String idMovie) {
        boolean result = false;
        // to-do algorithmic to solve this method
        return result;
    }

    // Static method
    public static boolean updateMovie(Movie movie) {
        boolean result = false;
        // to-do algorithmic to solve this method
        return result;
    }

    // Static method
    public static List<Movie> getAllMovies() {
        List<Movie> movies = new ArrayList<>();
        // to-do algorithmic to solve this method
        return movies;
    }

    // Static method
    public static List<Movie> findMovie(String title) {
        List<Movie> movies = new ArrayList<>();
        // to-do algorithmic to solve this method
        return movies;
    }
    
}

classDiagram
  class Movie {
    -title: String
    -reviews: List<Review>
    -director: Director
  }
  
  class Critic {
    -publications: int
  }
  
  class Director {
    -oscars: int
  }
  class Review {
    -rating: int
    -comment: String
    -critic: Critic
  }
  class Person {
    -name: String
  }
  
  class MovieManager {
    -static boolean deleteMovie(id)$
    -static boolean createMovie(id)$
    -static boolean updateMovie(id)$
    -getAllMovies()$ List~Movie~
    -findMovie(id)$ List~Movie
  }

  MovieManager -- Movie
  Movie *-- Review
  Movie *-- Director
  Review o-- Critic
  Person <-- Director
  Person <-- Critic

1.4 static class

When applied to a class, the static modifier indicates that the class is a nested class. In other words, the static class is defined inside another class, and is associated with the outer class.

Account.java
public class Account {
    // Static field
    private static int nextAccountNumber = 1;

    // Private instance variables
    private int accountNumber;
    private String name;
    private double balance;

    // Static nested class
    public static class Transaction {
        // Private instance variables
        private int transactionNumber;
        private double amount;
        private String type;

        // Constructor
        public Transaction(double amount, String type) {
            this.transactionNumber = nextAccountNumber++;
            this.amount = amount;
            this.type = type;
        }

        // Getter method for the transactionNumber field
        public int getTransactionNumber() {
            return transactionNumber;
        }

        // Getter method for the amount field
        public double getAmount() {
            return amount;
        }

        // Getter method for the type field
        public String getType() {
            return type;
        }
    }

    // Constructor
    public Account(String name, double balance) {
        this.accountNumber = nextAccountNumber++;
        this.name = name;
        this.balance = balance;
    }

    // Getter method for the accountNumber field
    public int getAccountNumber() {
        return accountNumber;
    }

    // Getter method for the name field
    public String getName() {
        return name;
    }

    // Getter method for the balance field
    public double getBalance() {
        return balance;
    }

}

Here is an example of how the static modifier can be used when applied to a class in Java, using an Account class and a nested Transaction class as examples:

2 static scope

In Java SE (Standard Edition), the term “static scope” typically refers to the visibility and accessibility of variables and methods marked with the static keyword within a class or interface.

When a variable or method is declared as static within a class or interface, it means that it belongs to the class itself rather than to instances of the class. This has implications for how these members are accessed:

  • Visibility within the class: Static variables and methods can be accessed directly within other static methods or variables of the same class without needing an instance of the class.

  • Access from outside the class: Static variables and methods can also be accessed directly using the class name, without needing an instance of the class. This access can occur from other classes, as long as the static member is declared with appropriate access modifiers (e.g., public, protected, or private).

  • Lifetime: Static variables exist for the entire duration of the program’s execution, and there is only one instance of each static variable per class, shared by all instances of the class.

  • Initialization: Static variables are initialized only once, at the start of the program execution, before any instances of the class are created.

Here’s a basic example to illustrate static scope:

Account.java
public class MyClass {
    // Static variable
    public static int staticVariable = 10;
    
    // Instance variable
    public int instanceVariable;
    
    // Static method
    public static void staticMethod() {
        System.out.println("This is a static method.");
        // Can access static variables directly
        System.out.println("Static variable: " + staticVariable);
        // Cannot access instance variables directly
        // System.out.println("Instance variable: " + instanceVariable); // This line would cause a compilation error
    }
    
    // Instance method
    public void instanceMethod() {
        System.out.println("This is an instance method.");
        // Can access both static and instance variables directly
        System.out.println("Static variable: " + staticVariable);
        System.out.println("Instance variable: " + instanceVariable);
    }
}

In this example, staticVariable is a static variable that can be accessed directly within both staticMethod() and instanceMethod(), while instanceVariable is an instance variable that can only be accessed within instanceMethod() or other instance methods, requiring an instance of MyClass.

3 static vs. non-static

3.0.1 Pros & cons usage static methods

Pros of making a method static Cons of making a method static
Can be called directly on the class, without needing to create an instance Cannot access non-static fields and methods of the class
Can be used as utility methods that don’t depend on the state of an object Can only work with the parameters passed to it and not use information unique to each object or instance
Can be used to access only static variables and methods, making it more efficient Can be challenging to make sure all instances of a class are modified consistently when using static methods

3.0.2 Pros & cons usage non-static methods

Pros of making a method non-static Cons of making a method non-static
Can access both static and non-static fields and methods of the class, allowing it to use the state of an object to determine its behavior Can only be called on an instance of the class, so you need to create an object of a class before using the method
Are associated with an instance of the class, so they can use the information that is unique to each object Can cause confusion when working with non-static methods because it could be called on different instances, which could cause unexpected behavior
Object-oriented design principles promote the use of non-static methods because they can be overridden by subclasses to change their behavior