Behaviour of final static method
Static methods cannot be overridden but they can be hidden. The ts()
method of B is not overriding(not subject to polymorphism) the ts()
of A but it will hide it. If you call ts()
in B (NOT A.ts()
or B.ts()
... just ts()
), the one of B will be called and not A. Since this is not subjected to polymorphism, the call ts()
in A will never be redirected to the one in B.
The keyword final
will disable the method from being hidden. So they cannot be hidden and an attempt to do so will result in a compiler error.
Hope this helps.
Is it a bad idea to declare a final static method?
I don't consider it's bad practice to mark a static
method as final
.
As you found out, final
will prevent the method from being hidden by subclasses which is very good news imho.
I'm quite surprised by your statement:
Re-defining method() as final in Foo will disable the ability for Bar to hide it, and re-running main() will output:
in Foo
in Foo
No, marking the method as final
in Foo
will prevent Bar
from compiling. At least in Eclipse I'm getting:
Exception in thread "main" java.lang.Error: Unresolved compilation problem: Cannot override the final method from Foo
Also, I think people should always invoke static
method qualifying them with the class name even within the class itself:
class Foo
{
private static final void foo()
{
System.out.println("hollywood!");
}
public Foo()
{
foo(); // both compile
Foo.foo(); // but I prefer this one
}
}
static final method in Java
If you look at JLS 8.4.3.3 final Methods, you'll see that the final
method modifier prevents methods from either being overridden or hidden.
A method can be declared final to prevent subclasses from overriding or hiding it.
It is a compile-time error to attempt to override or hide a final method.
A static
method cannot be overridden, but it can be hidden. The final
modifier prevents it from being hidden by a sub-class static
method.
static, final, static final - correct usage and when to use them?
static
means that a field or method belongs to the class, as opposed to individual instances of the class.
final
actually means different things when applied to methods versus fields (or local variables):
final
variables and fields cannot be reassigned. This is fairly similar to C++'sconst
.final
methods cannot be overridden, which only applies to methods on instances. When used in this sense,final
is not similar to C++'sconst
.
Because you cannot override static
methods on classes, the combined modifiers static final
are usually redundant, which is why IntelliJ advises you to remove one of the modifiers.
Additional notes:
final
variables and fields can refer to instances that may change, even though the references themselves cannot change.- Though you didn't ask about classes,
final
has a third meaning there:final
classes cannot be subclassed.static
can also be applied to nested classes (classes within classes), but it has the same meaning: Astatic
nested class does not belong to exactly one instance of the enclosing class, which it would otherwise. - Though
static
methods cannot be overridden, there's a similar behavior called "shadowing" or "method hiding", by which a subclass offers a static method of the same name and signature as the subclass. This behaves differently from overriding, but similarly,static final
methods cannot be shadowed.
Related SO question: "Is it a bad idea to declare a final static method?"
What is the reason for compile warning static method declared final?
Static methods are not subject to overriding.
The final
keyword hides the method. See the link in comments for more details.
Note that you should not rely on that behavior, although the language allows it. You should always invoke static methods as <class-name>.<method-name>
.
final class with final static methods redundant
Final classes cannot be extended in the first place, so it does not matter whether or not their methods are marked as final
.
For example, this will fail:
final class Util {
}
class Extra extends Util {
}
error: cannot inherit from final Util
class Extra extends Util {
Are static functions in a final class implicitly final?
In a final class, all methods are implicitly final as well because making the class final means it cannot be inherited from and thus there can be no hiding or overriding of its methods in child classes.
As a result, effectively you are correct that a static method in a final class is final, but it's not because of the fact that it's a static method. It's because the class is final.
Difference between Static and final?
The static keyword can be used in 4 scenarios
- static variables
- static methods
- static blocks of code
- static nested class
Let's look at static variables and static methods first.
Static variable
- It is a variable which belongs to the class and not to object (instance).
- Static variables are initialized only once, at the start of the execution. These variables will be initialized first, before the initialization of any instance variables.
- A single copy to be shared by all instances of the class.
- A static variable can be accessed directly by the class name and doesn’t need any object.
- Syntax:
Class.variable
Static method
- It is a method which belongs to the class and not to the object (instance).
- A static method can access only static data. It can not access non-static data (instance variables) unless it has/creates an instance of the class.
- A static method can call only other static methods and can not call a non-static method from it unless it has/creates an instance of the class.
- A static method can be accessed directly by the class name and doesn’t need any object.
- Syntax:
Class.methodName()
- A static method cannot refer to
this
orsuper
keywords in anyway.
Static class
Java also has "static nested classes". A static nested class is just one which doesn't implicitly have a reference to an instance of the outer class.
Static nested classes can have instance methods and static methods.
There's no such thing as a top-level static class in Java.
Side note:
main method is
static
since it must be be accessible for an application to run before any instantiation takes place.
final
keyword is used in several different contexts to define an entity which cannot later be changed.
A
final
class cannot be subclassed. This is done for reasons of security and efficiency. Accordingly, many of the Java standard library classes arefinal
, for examplejava.lang.System
andjava.lang.String
. All methods in afinal
class are implicitlyfinal
.A
final
method can't be overridden by subclasses. This is used to prevent unexpected behavior from a subclass altering a method that may be crucial to the function or consistency of the class.A
final
variable can only be initialized once, either via an initializer or an assignment statement. It does not need to be initialized at the point of declaration: this is called ablank final
variable. A blank final instance variable of a class must be definitely assigned at the end of every constructor of the class in which it is declared; similarly, a blank final static variable must be definitely assigned in a static initializer of the class in which it is declared; otherwise, a compile-time error occurs in both cases.
Note: If the variable is a reference, this means that the variable cannot be re-bound to reference another object. But the object that it references is still mutable, if it was originally mutable.
When an anonymous inner class is defined within the body of a method, all variables declared final
in the scope of that method are accessible from within the inner class. Once it has been assigned, the value of the final variable cannot change.
Behaviour of final static method
Static methods cannot be overridden but they can be hidden. The ts()
method of B is not overriding(not subject to polymorphism) the ts()
of A but it will hide it. If you call ts()
in B (NOT A.ts()
or B.ts()
... just ts()
), the one of B will be called and not A. Since this is not subjected to polymorphism, the call ts()
in A will never be redirected to the one in B.
The keyword final
will disable the method from being hidden. So they cannot be hidden and an attempt to do so will result in a compiler error.
Hope this helps.
Related Topics
Prime Numbers by Eratosthenes Quicker Sequential Than Concurrently
How to Have Explained the Difference Between an Interface and an Abstract Class
Difference Between Java Se/Ee/Me
Reversing a Linked List in Java, Recursively
When Should I Use File.Separator and When File.Pathseparator
How to Go About Formatting 1200 to 1.2K in Java
Date Format Mapping to JSON Jackson
Break or Return from Java 8 Stream Foreach
Jvm Takes a Long Time to Resolve Ip-Address for Localhost
How to Create Custom Methods for Use in Spring Security Expression Language Annotations
Java Annotations Values Provided in Dynamic Manner
Why Java Polymorphism Not Work in My Example
How to Create and Handle Composite Primary Key in JPA
No Suitable Driver Found for 'Jdbc:Mysql://Localhost:3306/Mysql