Skip to main content

super() as first is a problem

6 replies [Last post]
netsql
Offline
Joined: 2004-03-07
Points: 0

In other OO langs... in constuctor... the super() does not have to be the 1st command.

There is all kinds of workarroduns we do in Java to get arround that.

.V

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
tackline
Offline
Joined: 2003-06-19
Points: 0

The really useful thing to be able to do is set up member variables before calling the super. Self-encapsulation and template methods can cause havoc. Unfortunately this change would cause incompatibility and done reasonably would not allow explicit or implicit reference to 'this' in initialisation expressions (for instance, anonymous inner class expressions).

paulrivers
Offline
Joined: 2004-03-04
Points: 0

I agree, it's an overly simplistic restriction that I periodically run into. The other two posts already reflect my thoughts, so I won't repeat them.

I'd just like to say that it seems like the restriction should be that you cannot access any instance variables or instance methods until super is called.

Actually, I'm not sure why you couldn't access any instance variables in the current class. Perhaps you simply use any instance variables or methods in the super class until the super() constructor was called?

vpatryshev
Offline
Joined: 2004-06-30
Points: 0

Still, having super() as the first operator saves us from a lot of huge, huge troubles. Just makes code safer.

Although... well, at least they could probably let us use static methods and evaluate local variables.

But... on the other hand - what for? All that needed to be calculated before super() should be passed to super() as a parameter, right? Why else. So, all these calculations could be extracted into a static method.

Am I wrong?

yishai
Offline
Joined: 2003-11-16
Points: 0

> But... on the other hand - what for? All that needed
> to be calculated before super() should be passed to
> super() as a parameter, right? Why else. So, all
> these calculations could be extracted into a static
> method.
>
> Am I wrong?

Generally that is enough. There are two cases where that doesn't work for me:

1) If I need to evaluate which super to call. For example, JDialog takes a parent as a Frame or as a Dialog, but not as a Window. That means that the only way for me to instantiate a subclass that wants to support either as a parent and take it as a prameter is to use a factory method. And that factory method can make for some ugly duplication. The real solutions is to fix the Dialog class to take a Window as a parent (throw a RuntimeException if it isn't an instance of Dialog or Frame if you must for some reason. In my code I can be very confident I am not passing a raw Window), but the reality of such designs can force some ugly workarounds, made uglier by the lack of flexibility in super.

2) The other is the inability to put the call to super in a try block. Sometimes you do not want to have to throw out the superclass's exception, but would rather do something with it. Again the solution is a factory method, with some potentially ugly consequences (e.g. multiple attempts at instantiation).

Realistically, I don't know that #2 is fixable in Java. In another language that has different notions about how objects are instantiated, maybe. But Java wants to assume that the super object is completely instantiated first, and when there is an exception, that cannot be guaranteed.

jessewilson
Offline
Joined: 2003-06-14
Points: 0

Have you considered using a private constructor with a static factory method for your class? Something like this:
[code]class CoffeeMug extends BeverageHolder {
private CoffeeMug(Color color, liquid contents) {
super(contents);
}
public static CoffeeMug instance(Color color, liquid contents) {
try {
return new CoffeeMug(color, contents);
} catch(ContentsTooHotException e) {
// ignore
}
contents.addIceCubes(3);
return new CoffeeMug(color, contents);
}
}[/code]

Cheers,
Jesse
http://publicobject.com/glazedlists/

yishai
Offline
Joined: 2003-11-16
Points: 0

> Have you considered using a private constructor with
> a static factory method for your class?

Sure, that is the way around the problem. The biggest issue with that approach is that it kills the ability to further inherit from the class.

Another very substantial limitation in the current super requirements is the following case:

This is illegal (because of the implicit reference to this in a non-static inner class):

[code]
super(new AnonymousInnerClass(){
// Do something here.
});
[/code]

The solution to which would be this:

[code]
super(new StaticInnerClass());
[/code]

But wait, what if my static inner class needs to reference the outer class instance, like the anonymous class would be able to.

The solution is illegal:

[code]
super(new StaticInnerClass(this));
[/code]

This alone can send you off to a factory method. Sure, a good IDE like IDEA makes that switch easy, but the language is still tying you up in knots here.