Thursday, August 25, 2022

What is static and instance Method in Java? Example Tutorial

Hello guys, if you have trouble understanding what is static method in Java and how to use it then you are at the right place. In this article, I will share everything I have learned bout static method in my 20 years of Java experience. Static methods are one of the important programming concepts in any programming language but unfortunately, it is also the most misunderstood and misused one. Talking about Java, almost all programmers know that. static methods belong to the class and non-static methods belong to the objects of the class, but hardly all of them understand what it means. That's why this is one of the popular weed-out questions on programming interviews. 

If a Java programmer doesn't know the difference between static and non-static methods, he is probably not ready yet and needs more practice and experience. With half knowledge, making a method static can have serious repercussions, especially in today's heavily multi-threaded Java application.

Today, one of my reader message me this question on my Facebook account of Javarevisited, which prompted me to to write this tutorial cum discussion post to give a good explanation or example to clarify the concept. What you have learned is totally find, all we do here is to elaborate your learning by understanding key differences between static methods and instance methods in Java.

Let's start with what you have learned, static methods belong to the class, which means it can be called without a specific instance of that class. For example, the java.lang.Math class contains many static methods and you usually call them Math.random() to generate random numbers or Math.abs() to calculate the absolute value of a number. You don't need to create an instance of Math class to use these methods. 

This is quite convenient if you just want to use the functionality. Another example of the static method is the main method, which is usually static because it is called first before there is any time to instantiate a class. In fact, that is one of the reasons why main is static in Java.

On another hand, non-static methods can only be called on an instance of the class itself, and they usually do something that depends on the individual characteristic of the class (e.g. play with variables). 

They also have side effects e.g. calling a move() method on a Player object most likely changes its position. A key difference between static and non-static method is that static method affects all object if they are using any static variable, but non-static method only affects the object they are operating upon. Let's see an example to understand how a static and non-static method works.




Static vs Non-Static Method Example in Java

Here is a Java program to demonstrate and explain the difference between an instance method and a class method in Java. If you are using Eclipse IDE,  you can easily run this program by just copy-pasting in your Java project, no need to create Java source files and directories to represent package, Eclipse will take care of those things. 

In this program, we have two players P1 and P2, which are instance of Player class. This class contains a class variable called "game" and two instance variable X and Y to denote coordinates of Player. We have a static method called changeGame() to set value of static variable "game" and non-static method move() to change value of instance variables X and Y.

Static method in Java with Example

In the first example of our test program, we call instance method move() on p1 and you can see that only its X and Y are modified, p2's position has not changed because the instance method only affect the state of methods they were called upon. 

In the next example we call static method changeGame(), now this will affect both p1 and p2 because static variable "game" is shared between them. You can see the output after the invocation of instance method and static method to figure out difference.

/**
 * Java program to show difference between static and non-static method.
 * It explains how calling static method and changing static variable
 * affect all objects, instead of just calling object in case of non-static
 * method
 * @author WINDOWS 8
 *
 */
public class StaticDemo{

    public static void main(String args[]) {
        Player p1 = new Player(10, 10);
        Player p2 = new Player(20, 20);
     
        // calling non-static method move() on p1
        p1.move();
     
        // let's print position of p1 and p2
        // only p1 should have moved, no impact on p2
        System.out.println("P1 : " + p1);
        System.out.println("P2 : " + p2);
     
        // calling static method on p2
        p2.changeGame("Cricket Brian Lara 1997");
     
        // should have affected both p1 and p2
        System.out.println("P1 : " + p1);
        System.out.println("P2 : " + p2);
     
    }
 
 
 
}
/**
 * Simple Java class to represent a Player with position.
 * It has both static and non-static method to operate on
 * player objects.
 * @author WINDOWS 8
 *
 */
class Player{
    private static String game = "Super Mario Bros";
 
    private int X;
    private int Y;
 
    public Player(int x, int y){
        this.X = x;
        this.Y = y;
    }
 
    public void move(){
        X++;
        Y++;
    }
 
    public static void changeGame(String nextGame){
        game = nextGame;
    }
 
    @Override
    public String toString() {
        return String.format("Game: %s, X : %d, Y: %d ", game, X, Y);
    }
}

Output
P1 : Game: Super Mario Bros, X : 11, Y: 11
P2 : Game: Super Mario Bros, X : 20, Y: 20
P1 : Game: Cricket Brian Lara 1997, X : 11, Y: 11
P2 : Game: Cricket Brian Lara 1997, X : 20, Y: 20





Properties of static methods in Java

Static is not just another keyword it's one of most important programming concept and every language has some specific features related to static variables, methods, and classes. Though key difference comes from the fact that static is something which is associated with the class rather than an instance, there are many subtle details of static keyword, which you should keep in mind. Let's see some of them here.

1. You cannot use this keyword inside a static method in Java. Since this is associated with the current instance, it's not allowed in static context because no instance exist that time. Trying to use this variable inside static context e.g. static block or method is compile time error in Java.

2. super keyword is not allowed inside the body of a static method or static block. Just like this, a super keyword is also used to represent current instance of the parent class and since the instance is not valid in static context, it's a compile-time error to use super keyword inside a static method in Java.

3. You cannot use any instance variable inside a static method, they will result in compile time error e.g. "non-static reference is not allowed inside static methods". Why? because instance may not exist when the static method gets called. They are not associated with any instance, you can call them even on a null variable without throwing NullPointerException in Java. In short, you cannot use  non-static members inside your static methods in Java.

3. A static method cannot be overridden in Java, Why? because they are not resolved at runtime, which is the case with overriding. Like a private and final method, static methods are also resolved at compile time. 

By the way, this doesn't mean that you cannot declare another static method with same name and signature in the child class, you can do so and the compiler will not complain at all, but that would not be method overriding, instead that is called method hiding in Java. This new method will hide the static method from the parent class and when you call it using Child class only.  See why static method cannot be overridden for more details.

4. Static method invocation is more efficient than instance method because the compiler doesn't need to pass this reference, unlike instance methods. That's why you should make utility method as static if they are not using any instance variable.

5. Static methods are bonded during compile time, as opposed to an instance method, which is resolved during runtime; former is known as static binding while later is known as dynamic binding in Java. See the difference between static and dynamic binding for more details.



6. By the way, You can overload static methods in Java, there is no restriction on that from Java language perspective. In fact, JDK API itself has lots of overloaded static method e.g. String.valueOf() is overloaded to accept an int, long, float, double, and boolean data type. EnumSet.of() is also overloaded to create EnumSet with one, two or multiple values.

7. You can call a static method without creating any instance of that class, this is one of the biggest reason of making a method static in Java. For example, to call Double.valueOf(), you don't need to create an instance of the Double class. You can even call static methods with reference variable having a null value and to your surprise, those will not result in a null pointer, as only the classname is used to find and call static methods. For example, following code will run fine in Java.
Double d = null;
d.valueOf(2);

8. A static method can be synchronized, and more importantly, they use different lock than instance synchronized method. Which means, two threads can simultaneously run a static and a non-static method in Java. This is a common multi-threading mistake in Java and you should look for that while writing Java test involving code and multiple threads. To learn more see the difference between static and non-static synchronized method in Java.

9. You cannot declare a static method inside the body of an interface in Java.

10. As the name implies, instance methods require an instance of a class. Static methods (and fields) are independent of class instances, as they are only associated with class. To use instance methods, you'll have to create an instance using new. A static method is considered to have no side effect on the state of an object because of the said reason.




When to use Static method in Java? Example

Methods which never need to access instance variables are good candidate to become static. The functions in java.lang.Math are a good example as they only need input arguments. One rule-of-thumb, if you have a class MyClass,  ask yourself  "does it make sense to call this method, even if no Object of MyClass has been constructed yet?" If so, it should definitely be static.

Another simple rule in Java is,  Immutable is good. So if your method does not change the state of the object and if it must not be overridden by a subclass, it should be static. 

Also, static methods are easier to inline by the JIT-Compiler. Let's see an example, supper you have a class Car and you might have a method double convertMpgToKpl(double mpg) , this is another good candidate to become static, because one might want to know what 45mpg converts to, even if nobody has ever built a Car.

But void setOdometer(double mi) (which sets the distance-travelled for one particular Car) can't be static because it's inconceivable to call the method before any Car has been constructed. 

In short, If a method inside a class is not using an instance variable, then it's a good candidate for making it static, and maybe it might not belong to that class itself. Here are a couple of common scenarios in the Java world, where use of static method is considered appropriate :

1) Use static method as static factory method for data conversion e.g. Integer.valueOf(), which is used to convert any other data type to integer e.g. Integer.valueOf(String str) converts String to Integer in Java.

2) Use static method as utility methods like methods from Math class or Arrays or Collections e.g. Collections.sort() method.

3) getInstance() method of Singleton design pattern is another popular example of Static method in Java

4) Pattern.compile() is another static method, which is example of static factory method as discussed in the first example

5) Hmm, how can I forget the most popular example of a static method in Java,  yes I am talking about public static void main(String[] str). The main method is one of the most known examples of static methods, in fact, why main is static in Java, is also one of the frequently asked Java question on college viva or on Java interviews.





Disadvantages of using the static method in Java 

There is nothing in the world which only has pros without any cons, and static methods are no different. Though they are immensely helpful from convenience perspective and critical to implement some core Java design patterns like Singleton and Factory Pattern, they also have some serious drawbacks. Here is a couple of them :

1. No Runtime Polymorphism
First and foremost, the static method reduces the flexibility of your system. Once a method is declared static, it's fixed. You cannot provide an alternate implementation of that method in a subclass, as the static method cannot be overridden, they can only be hidden. Even this method hiding can cause serious and subtle bugs.

2. Potential of Concurrency Bugs
One of the not-so-obvious thing about static synchronized method is that it uses different lock than instance synchronized method. which means, If you are sharing a resource between a static and non-static method, and thinking that you have synchronized their access, you are living on a dream. Both methods can be run in parallel at the same time and potentially cause subtle concurrency bugs.

3. Lose of interface
You cannot declare a static method inside the interface in Java, so if your design has a static method, you cannot use the interface. You need to put your static method only on implementations, which means all code, which is written against the interface will not have access to that static method. Since programming to interface than implementation is one of the popular object-oriented design principles, you will see a lot of code written like that.


That's all about the difference between the static and non-static methods in Java. We have learned key points about static methods, have seen some popular examples of them, explored when to use static methods, and also learned about the potential disadvantage of using static methods. 

This gives you a fair idea about the capability and limitation of static methods in the Java programming language. Careful and clever use of this concept can result in a more readable and concise code while misuse can cause a lot of pain especially in areas of concurrency, flexibility, and maintainability.

Other Core Java Tutorials you may like

I have shared a lot of information about static methods in Java. These are very important for all Java developer, both beginners and experienced ones. Knowing this detail enable you to write correct and better Java programs. 

Another thing I also like to share that while static method was difficult to test earlier as they are bonded during compile time you cannot mock their behaviors but things have changed, now you can use Mockito test static method as well.


4 comments:

  1. IMHO, static methods are good for utility task but hey are not designed to change the state of an object. As best practice, static method should operate on local values passed to it and minimizing accessing member variables, I know you cannot use instance variable inside static method but static variables are allowed, but you shoudl minimize accessing it.

    ReplyDelete
  2. One of the most importatnt drawback of static methods are that they are hard to test. Since you cannot override static methods, its difficult to inject mocks and friendly object required for unit testing. Only way to test static method in Java is by using PowerMock library, which allows you to mock static methods.

    ReplyDelete
  3. Please check your article. I have tried static method inside interface in jdk 8. It has worked fine. Please check article

    ReplyDelete
    Replies
    1. Hello @Unknown, yes from JDK 8, you can use static method inside interfaces. In fact default methods can also be declared inside interface, but article is true for any JDK prior to JDK 8. Probably, I need to update this with latest information and changes made in JDK 8 with respect to static methods. Thanks

      Delete

Feel free to comment, ask questions if you have any doubt.