Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Why Static is allowed with Final  RSS feed

 
Jammy Wells
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hellow Guys

Java allows a method to be static and final , which means that it should allow overriding of static methods which is not true, take a look at my code below .....

class Stats
{
final static void m1()
{
System.out.println("Hello World!");
}
}

class StatsChild extends Stats
{
public static void main(String[] args)
{
System.out.println("Hello World!");
Stats st = null;

st.m1();

st = new StatsChild();

st.m1();
}

static void m1()
{
System.out.println("overidden --------");
}
}


The result for executing StatsChild is never "overidden --------", I am very confused with this , please help me out guys....
 
Jon Parise
Ranch Hand
Posts: 81
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Basically static makes it such that all instances of that class use that one instance of the variable/method.

They also can only access other static things, so if you call a static method on an instance of a class it can only use static variable/fields. Trying to access non static things will result in an error.


Final on the other hand makes it so that the method can never be overridden by a subclass. So if you make a method final you can't override it in the subclass. This is why you never get the output "overidden", it will still refer to the parent class's method since it was final. I'm surprised the compiler didn't yell at you for trying to override a final method.

By definition you can never overload a final method, thats the whole point of the final keyword.

The behavior you are seeing is totally correct. I know it's confusing, and I hope I didn't make it worse.
 
Rob Spoor
Sheriff
Posts: 21092
85
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jon Parise:
Final on the other hand makes it so that the method can never be overridden by a subclass. So if you make a method final you can't override it in the subclass. This is why you never get the output "overidden", it will still refer to the parent class's method since it was final. I'm surprised the compiler didn't yell at you for trying to override a final method.

Well actually, you never override a static method. Instead, you define a method with the same name and arguments, thereby hiding the original.
Now why you don't get overriden is because, unlike non-static methods, the compiler looks at the reference type, not the object type. Although the object is a StatsChild, it is declared to be a Stats, and so Stats.m1() is called. In fact, st could even be null! That's right, call a method on an object and don't get a NullPointerException! That's because it's not using the value of the reference variable, only the type.

By definition you can never overload a final method, thats the whole point of the final keyword.

Sure you can. You can't override a final method. This does not hold for static methods though, because you can't override them anyway.
 
marc weber
Sheriff
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's true that static methods cannot be overridden. See Overriding vs. Hiding.

So static methods are effectively "final" anyway. If you want to add the "final" keyword, it won't affect anything. But omitting the keyword won't affect anything either. It's irrelevant in this context.
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But final does have an affect on static methods - it prevents them from being hidden.

Although IntelliJ doesn't notice a problem , the compiler does, and correctly throws an error. But because the compiler writers don't always follow the JLS terminology, the compiler incorrectly complains that "foo() in B cannot override foo() in A; overridden method is static final". Well, technically that's true, B.foo() can't override A.foo() - but more relevant is the fact that it also can't hide A.foo(), because A.foo() is final.

In this respect, overriding and hiding behave the same way, and get the same compiler error message. In other ways of course, overriding and hiding are not the same.
[ October 22, 2007: Message edited by: Jim Yingst ]
 
marc weber
Sheriff
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Jim Yingst:
But final does have an effect on static methods - it prevents them from being hidden...

Geez... That totally slipped my mind!
 
Jammy Wells
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your enlightning replies guys....I apologise for posting wrong code I added final in the parent class method after executing the whole thing and then moved the code here....

Now I have got the clear picture that in case of static methods compiler just plays with the reference type not the object type.....

Thanks a ton for that guys...
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!