1

I have the following classes.

abstract class A{}

class B extends A{}

class C extends A{}

I need to create an object like this

A a = new B();

I get the class name of the subclass at runtime. So, I need to use reflection to create an object.

I have done this.

Class<?> klass = Class.forName(className);

Now I am not able to cast this class to the subclass.

I want to achieve

A a = klass.newInstance(); // returns Object

I want the object to be casted into the subclass (either B or C, decided on runtime)

How do I do this?

8
  • 3
    What's wrong with A a = (A)klass.newInstance(); ? Commented Jun 26, 2013 at 13:35
  • @AleksG I need to access the functions in the subclass. Commented Jun 26, 2013 at 13:39
  • What's wrong with switch (name) { case "B": return new B(); case "C": return new C(); default: throw new SomeException(); }? / What's wrong with Class.newInstance? Plenty. If you're going through Constructor.newInstance, better to use asSubclass up front. Commented Jun 26, 2013 at 13:39
  • 1
    Since you are using reflection anyway, you don't really have to cast them to use the functions in the subclass... Commented Jun 26, 2013 at 13:41
  • 1
    @rgksugan There's nothing clean about reflection. Commented Jun 26, 2013 at 13:52

4 Answers 4

3

You can use Generics to declare

Class<? extends A> klass;

then you'll be allowed to write

A a = klass.newInstance();

However, since Class.forName has no type information on your class, and has no type inference declared, you'll be getting "unchecked cast" warnings. This approach is no more typesafe than just downcasting the result of the second line to A.

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

3 Comments

Incompatible types. found: Class<capture<?>>
Yes. You need an explicit cast on the right-hand side. Anyway, it doesn't give you much mileage: you can't make an inherently type-unsafe piece of code type-safe.
A a = Class.forName( … ).asSubclass(A.class).newInstance(); does even work without unchecked type casts and is type safe.
2

I want the object to be casted into the subclass (either B or C, decided on runtime)

That makes no sense. Casting is something which is primarily a compile-time operation, to end up with an expression of the appropriate type. It's then verified at execution time.

If you're really trying to achieve a variable of type A, then you only need to cast to A:

A a = (A) klass.newInstance();

Comments

0

Having klass object of type Class<T> you can call Class.cast() method to cast to type T using

klass.cast(object)

For example, you have a of type B, you cast a to type B loaded at runtime.

Class<?> klass = Class.forName("B");
klass.cast(a);

Comments

0

To follow up on the comments, you can create your instance of the class with either

Class klass = Class.forName(className);
A a = (A)klass.newInstance();

or

Class<? extends A> klass = Class.forName(className);
A a = klass.newInstance();

Then you can invoke a method on it with:

klass.getMethod(methodName, null).invoke();

Or, if the method takes arguments (e.g. int and String)

int param1 = ...;
String param2 = ...;
klass.getMethod(a, new Class[] { Integer.class, String.class }).invoke(param1, param2);

Of course, you'll need to be catching appropriate exceptions.

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.