5

Is it possible to create an instance of a derived class in abstract ancestor class using reflection Lets say:

abstract class Base {

public Base createInstance(){
  //using reflection
    Class<?> c = this.getClass();
    Constructor<?> ctor = c.getConstructor();
    return ((Base) ctor.newInstance());
}

}//end Base

class Derived extends Base {

 main(){

new Derived().createInstance()

 }

}

5
  • 2
    Did you try it? Seems like it would work. Commented Nov 19, 2012 at 9:33
  • 1
    What happened when you tried? You can do this but its a fairly suspect design choice. Commented Nov 19, 2012 at 9:33
  • @PeterLawrey It could be justified as a copy-method. Commented Nov 19, 2012 at 9:34
  • Note that you are wasting lines of code: public Base createInstance() { return (Base) getClass().newInstance(); } is all you need (module exceptions). Commented Nov 19, 2012 at 9:35
  • Umm. That code would not even compile at the first place. Anyways, what happened when you tried it?> Commented Nov 19, 2012 at 9:36

3 Answers 3

3

You can do this

public class Derived extends Base {
    public static void main(String ... args) {
        System.out.println(new Derived().createInstance());
    }
}

abstract class Base {
    public Base createInstance() {
        //using reflection
        try {
            return getClass().asSubclass(Base.class).newInstance();
        } catch (Exception e) {
            throw new AssertionError(e);
        }
    }
}

prints

Derived@55fe910c

A more common pattern is to use Cloneable

public class Derived extends Base {
    public static void main(String ... args) throws CloneNotSupportedException {
        System.out.println(new Derived().clone());
    }
}

abstract class Base implements Cloneable {
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

prints

Derived@8071a97

However, the need to use either should be avoided. Usually there is another way to do what you need so that base doesn't not implicitly depend on derived.

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

Comments

2

Proving it works is easy:

abstract class Base {
  public Base createInstance() throws Exception {
    return getClass().newInstance();
  }
}

public class Derived extends Base {
  public static void main(String[] args) throws Exception {
    System.out.println(new Derived().createInstance().getClass());
  }
}

prints

class test.Derived

You should ask yourself twice why you need it and whether it is really a good approach for your problem. If you need cloning, consider the clone mechanism, which does basically the same thing.

2 Comments

I am trying to write an API(cover Base abstract class). And I need deepCopy method for this Base class.
Deep copying cannot be solved in the general, anyway. You'll need carefully thought-through custom code for each class. That's why you gain very little by generalizing instance creation code.
1

You can use Class.forName() and Class.newInstance() to create any class. But there's no way to easily identify subclasses of a class. See this JavaWorld tip for a technique to do this.

I think , however, the real issue is what is it you're ultimately trying to achieve, and can it be done more easily using conventional techniques.

Comments

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.