How to Override and Overload Static Methods in Java

How to overload / override static method to return an other value?

You definitely cannot override a static method. However, you can mock a static method with a lot of work. Generally, mocking a static method isn't a good sign. Fortunately, there are libraries out there that can do this if you need it.

Mockito has added support for this and there is a pretty good tutorial from Baeldung demonstrating how to do this: https://www.baeldung.com/mockito-mock-static-methods#mocking-a-no-argument-static-method.

Based on the tutorial:

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
@Test
void mockLibraryIsActivated() {

// Before mocking the static method is going to return false
assertFalse(Library.isActivated());

// Using MockedStatic to mock the method
try (MockedStatic<Library> utilities = Mockito.mockStatic(Library.class)) {
utilities.when(Library::isActivated).thenReturn(true);

// Perform your test, the mock only works within the try block
assertTrue(Library.isActivated());
}

// Mock is no longer active
assertFalse(Library.isActivated());
}

The one key limitation to this is that the mock only applies within the code block it is defined in. So if you had another unit test you would also have to mock it within that unit test.

If you really want to dive down the rabbit hole you can look at how MockitoCore.mockStatic is implemented in the GitHub repo: https://github.com/mockito/mockito/blob/main/src/main/java/org/mockito/internal/MockitoCore.java.

Why doesn't Java allow overriding of static methods?

Overriding depends on having an instance of a class. The point of polymorphism is that you can subclass a class and the objects implementing those subclasses will have different behaviors for the same methods defined in the superclass (and overridden in the subclasses). A static method is not associated with any instance of a class so the concept is not applicable.

There were two considerations driving Java's design that impacted this. One was a concern with performance: there had been a lot of criticism of Smalltalk about it being too slow (garbage collection and polymorphic calls being part of that) and Java's creators were determined to avoid that. Another was the decision that the target audience for Java was C++ developers. Making static methods work the way they do had the benefit of familiarity for C++ programmers and was also very fast, because there's no need to wait until runtime to figure out which method to call.

Method overloading with both static and non-static methods

Use of keyword static doesn't make a difference in method overloading.

Your code compiles because the method signature of both add() methods are different (2 params vs 3 params).

However, if you were to write something like this, then it would result in a compilation error.

class Adder {
static int add(int a, int b) {
return a + b;
}

int add(int a, int b) {
return a + b;
}
}

Java Overloaded AND Overridden Methods

Since overloading and overriding both exist in this code, does that mean that it performed static binding at compile time (to the matching method in class A) and then dynamic binding at run time (to method in class B)

Right. The compiler chose the matching signature, and this is static, based on the type of the variable (A in this case).

At runtime, Java finds the implementation of the signature selected by the compiler. This is dynamic, based on the runtime class of obj3 (B, in this case).



Related Topics



Leave a reply



Submit