Overriding static methods - why doesn´t it work?

T

Thomas Strandh

When trying to override static methods in Java (1.5.x) you get unexpected
results.
The overriding doesn't work they way you expect.




When running the sample code below you get the following output:

Static overloading: 2 1

Instance overloading: 20 20




I expected this output:

Static overloading: 2 2

Instance overloading: 20 20




My opinion is that this behaviour is a bug.

It violates the fundametals of object oriented programming.




- Can you give me a reason why the JVM treats the overrided static methods
this way?




Code sample follows:




/*

* SubClass.java

*

* Created on den 23 juni 2005, 21:13

*/




package sample;




/**

*

* @author Thomas

*/

public class SubClass extends SuperClass{


public static Long getStaticLongId(){

return 2L;

}


public Long getInstanceLongId(){

return 20L;

}


public static final void main(String args[]){

SubClass subClassInstance = new SubClass();

System.out.println("Static overloading:\t" +

SubClass.getStaticLongId() + "\t" +

SubClass.getStaticStringId());

System.out.println("Instance overloading:\t"+

subClassInstance.getInstanceLongId() + "\t" +

subClassInstance.getInstanceStringId());

}

}




/*

* SuperClass.java

*

* Created on den 23 juni 2005, 21:09

*/




package sample;




/**

*

* @author Thomas

*/

public class SuperClass {


public static Long getStaticLongId(){

return 1L;

}


public static String getStaticStringId(){

return getStaticLongId().toString();

}


public Long getInstanceLongId(){

return 10L;

}


public String getInstanceStringId(){

return getInstanceLongId().toString();

}

}
 
R

R.F. Pels

Thomas said:
When trying to override static methods in Java (1.5.x) you get unexpected
results. The overriding doesn't work they way you expect.

Well, static methods are class-methods, not object-methods. Huh?

Normally, in OO, you specify for which object you want to invoke a method.
This means that the invocation always needs to carry information on what
object the method is invoked on and what the type of the object is.

This is not necessary for class-methods. Static methods can be invoked
regardless of the fact that you have an object of that type or a derived
type. And since it cannot assume the existence of an object, it also cannot
make use of information regarding overriding of methods, hence it calls the
static method that belongs to the class it belongs to.
My opinion is that this behaviour is a bug.
It violates the fundametals of object oriented programming.

It is not a bug. And it does not violate OOP. In fact, a constructor is also
a class-method. How else can it be called before an object of that type
exists?
 
O

Owen Jacobson

When trying to override static methods in Java (1.5.x) you get unexpected
results.
The overriding doesn't work they way you expect.

Java doesn't allow you to "override" static methods as such. A derived
class may contain a static method with the same signature as a parent
class; neither is in any way affected by the other.

I believe the problem is that exposes static methods through derived
classes at all (and don't get me started on exposing them through
object references). It's almost always bad style.
When running the sample code below you get the following output:

Actually, it doesn't compile for me, but that's only because I have my IDE
set up to treat warnings as errors.
Static overloading: 2 1
Instance overloading: 20 20

I expected this output:

Static overloading: 2 2
Instance overloading: 20 20
(snip)

It violates the fundametals of object oriented programming.

Static methods in general do that, being (as they are) behaviour that is
_not_ attached to an object. That doesn't make them bad, it just means
that applying OO expectations to them isn't helpful.
- Can you give me a reason why the JVM treats the overrided static
methods this way?

Looking strictly at SuperClass.getStaticStringId (), what information
should it use to dispatch getStaticLongId () to the derived class?
There's no "this" object, remember.
 
J

John C. Bollinger

Thomas said:
When trying to override static methods in Java (1.5.x) you get unexpected
results.

I suppose it depends on what your expectations are.
The overriding doesn't work they way you expect.

More accurately, overriding static methods doesn't work at all, and
never has done. This is because static methods are not virtual. It is
an intentional design feature of the language.
 
C

Chris Uppal

Thomas said:
When trying to override static methods in Java (1.5.x) you get unexpected
results.
[...]
My opinion is that this behaviour is a bug.

It violates the fundametals of object oriented programming.

It's not a bug, that's the way the language is specified to work. It's one of
the fundamental design-features of the language.

Of course, you may consider that that means that the language design is
fundamentally broken. If so then I agree with you. At the very least, static
"methods" have nothing to do with OO.

You may also consider that static methods should be avoided (within reason). I
think that a lot of good Java programmers would agree with you.

-- chris
 
J

Joan

Chris Uppal said:
Thomas said:
When trying to override static methods in Java (1.5.x) you get unexpected
results.
[...]
My opinion is that this behaviour is a bug.

It violates the fundametals of object oriented programming.

It's not a bug, that's the way the language is specified to work. It's one of
the fundamental design-features of the language.

If it is a design-feature that it is not supposed to work then should not
the compiler
or run time system generate an error message or warning of some sort?
 
T

Tor Iver Wilhelmsen

Joan said:
If it is a design-feature that it is not supposed to work then
should not the compiler or run time system generate an error message
or warning of some sort?

Eclipse will warn you if you try to access static members (methods or
fields) via an instance reference. But it does not flag it an error,
since - according to the language specification - it's allowed and
well-defined.
 
O

Owen Jacobson

Eclipse will warn you if you try to access static members (methods or
fields) via an instance reference. But it does not flag it an error, since
- according to the language specification - it's allowed and well-defined.

It can be made to treat that specific warning as an error.

It can also be made to treat access to a superclass's static methods
through a subclass's name as an error. I find these very handy for
catching this sort of silliness.
 
C

Chris Uppal

Joan said:
If it is a design-feature that it is not supposed to work then should not
the compiler
or run time system generate an error message or warning of some sort?

But is /is/ supposed to work. The relationship between static methods in
classes and similarly named static methods in subclasses is clearly defined,
and does not include overriding. Why should the compiler issue warnings ?

A good case could be made for a tool such as Eclipse to warn when it saw
constructions that /might/ indicate that the programmer didn't understand Java,
but I don't think that's the compiler's job.

-- chris
 
A

Antti S. Brax

In fact, a constructor is also a class-method. How else can it be
called before an object of that type exists?

That is a very silly example. Constructor may be called before
an object of that type exists, but it is never executed before
an object exists.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top