Is it possible to do the calculation before super () in the constructor?

Given that I have a Base class that has a single argument constructor with a TextBox as an argument. If I have a Simple class like this:

public class Simple extends Base { public Simple(){ TextBox t = new TextBox(); super(t); //wouldn't it be nice if I could do things with t down here? } } 

I get an error message indicating that the super call should be the first call in the constructor. However, oddly enough, I can do this.

 public class Simple extends Base { public Simple(){ super(new TextBox()); } } 

Why is this allowed, but the first example is not? I can understand that you need to configure the subclass first and possibly not allow the creation of object variables before calling the superconstructor. But t is obviously a method (local) variable, so why not allow it?

Is there a way around this limitation? Is there a good and safe way to keep variables in things that you could create before calling super, but AFTER you entered the constructor? Or, more generally, allowing you to do the calculation before the super is actually called, but inside the constructor?

Thank.

+44
java
Feb 20 '10 at 20:28
source share
5 answers

Yes, there is a workaround for your simple case. You can create a private constructor that takes a TextBox as an argument and calls it from your public constructor.

 public class Simple extends Base { private Simple(TextBox t) { super(t); // continue doing stuff with t here } public Simple() { this(new TextBox()); } } 

For more complex things, you need to use the factory or the static factory method.

+50
Feb 20 '10 at 21:03
source share

I had the same problem with the calculation before the super call. Sometimes you want to check some conditions before calling super() . For example, you have a class that uses a lot of resources when creating. the subclass requires additional data and can check it first before invoking the super constructor. There is an easy way to solve this problem. may seem a little strange, but it works well:

Use a private static method inside your class that returns a super constructor argument and does its checks inside:

 public class Simple extends Base { public Simple(){ super(createTextBox()); } private static TextBox createTextBox() { TextBox t = new TextBox(); t.doSomething(); // ... or more return t; } } 
+15
Jul 21 '13 at 4:57
source share

required in this language to ensure that the superclass is reliably constructed first. In particular, "If the constructor does not explicitly call the constructor of the superclass, the Java compiler automatically inserts a call to the constructor without arguments to the superclass."

In your example, the superclass can rely on state t at build time. You can always ask for a copy later.

It is discussed in detail here.

+5
Feb 20 '10 at
source share

The reason that the second example is allowed, but not the first, is likely to keep the language in order and not introduce strange rules.

Allowing any code to run before the super was invoked would be dangerous, as you might encounter things that should have been initialized but still not. Basically, I think you can do quite a lot of things in calling super itself (for example, calling a static method to calculate some material that needs to be passed to the constructor), but you can never use anything from an ith-fully constructed object , what well.

0
Feb 20 2018-10-20
source share

How Java Works :-) There are technical reasons why it was chosen this way. Perhaps it is strange that you cannot perform calculations on local computers before calling super, but in Java, an object must first be selected and, therefore, it must go all the way to the object so that all fields are correctly initialized before you can accidentally modify them.

In your case, getter is most often used, which allows you to access the parameter provided by super (). Therefore you should use this:

 super (new TextBox ());
 final TextBox box = getWidget ();
 ... do your thing ...
0
Feb 20 '10 at 20:59
source share



All Articles