4

I have a class that's essentially like:

class Child extends Parent {
  public void reinitialize() {
    super();  // illegal
  }
}

Basically, I want to call the constructor again to reinitialize. I can't refactor out the initialization code into its own method, because Parent is a library class I can't modify the source of.

Is there a way to do this?

3
  • do you wanna reinitialize parent or child?? Commented Dec 9, 2012 at 20:07
  • Create an initialize() method which does what your constructor currently does. Then, your constructor and reinitialize() should both simply call initialize(). Commented Dec 9, 2012 at 20:08
  • @Gan: Child (so I could instead call this()). Vulcan: As mentioned, I cannot refactor due to not having the source for Parent. Commented Dec 9, 2012 at 20:28

4 Answers 4

7

No, there is no way to do this. Even at the JVM bytecode level, a chain of <init> methods (constructors) can be called at most once on any given object.

The usual answer is to refactor the code out into a normal instance method, but as you said, this is impossible.

The best you can do is to find a way to redesign to get around the need for reinitialization. Alternatively, if there's a specific behavior in the parent constructor you need, you might be able to duplicate it yourself.

Sign up to request clarification or add additional context in comments.

9 Comments

You can follow the design principle "favor composition over inheritance" (Effective Java), thus making Child having a Parent (composition), instead of being one (inheritance). This way, you can exchange the parent with a new instance, thus calling the constructor.
That's included under the refactoring option. I'm assuming that the OP can't do this due to library design.
As I understood it, s/he can't change Parent, but Child is a subclass written by himself.
If the restriction is only on calling <init> more than once, can't it be worked around by instantiating Child using Objenesis (which will skip the first call to the constructor)?
@user833771 No - ctor can be called at most once at the bytecode level. In particular, it can only be called on an uninitialized object, and not at all on an already initialized object. Even if you use dark magic to create an initialized object without calling the ctor, you can't call the ctor on it because the verifier sees it as already initialized.
|
3

The only work around for this is to either

  • create a new object each time you need to "re-intialise" it.
  • use delegation instead of inheritance, even if you have to use both. By using delegation you can replace the instance.
  • create a re-initialise method which does much the same thing as the parent constructor. e.g. replace fields or clear collections, using reflections if you have to.

Comments

1

One way to do this is provide a static method which returns a new Child object. Alternatively, you can simply create a new Child object in the client code. Either way, it sounds like you will be unable to reuse an existing object.

Comments

0

There are several ways to achieve this. One of them is create another method, for example "init". This "init" method should be invoked from either the constructor or the reinitialize method.

1 Comment

Thanks, but as mentioned in the question, I can't modify the parent class' constructor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.