Cast an object to class type passed as parameter
Solution 1
If you add a constraint to child
, you don't need a cast at all to get a Parent:
Parent func(Class<? extends Parent> child, String whichChild) throws Exception {
// whichChild: "ChildA" or "ChildB"
Parent obj = child.newInstance();
//...
}
However, you still can't call the testChildA
etc method, since all you have is an instance of Parent
. You'd need to use reflection to get the method:
Method method = obj.getClass().getMethod().getMethod("test" + whichChild);
method.invoke(obj);
It would be better to have a method on the interface of Parent
which you can invoke, and is overridden in the subclasses.
public abstract class Parent {
public void test() {
System.out.println("Test from parent");
}
public abstract void testChild();
}
then simply call:
obj.testChild();
or, as Emanuele Ivaldi points out, just override test
in ChildA
and ChildB
and invoke that directly.
Solution 2
Not sure exactly what you're doing but you can use Class.cast(...)
.
Eg
public <T> T getInstance(Class<T> type) {
Object o = type.newInstance();
T t = type.cast(o);
return t;
}
hakuna matata
Updated on July 09, 2022Comments
-
hakuna matata almost 2 years
I have a parent class and 2 child classes. I am trying to implement a function that takes the type of the child and which child as parameters.
When I use
child.newInstance()
, I want to store it in a variable of the type that is passed and call a function from the second parameter.Below are the classes
public class Parent { public void test() { System.out.println("Test from parent"); } } public class ChildA extends Parent { public void testChildA() { System.out.println("Test from child a"); } } public class ChildB extends Parent { public void testChildB() { System.out.println("Test from child b"); } }
and here is the method I'm trying to implement
public class Driver { Parent func(Class child, String whichChild) throws Exception { // whichChild: "ChildA" or "ChildB" Object obj = child.newInstance(); // cast obj to type of child and call the method "test" and "test" + whichChild } }
Can it be done what I am trying to do? If yes, how can I cast this object to the type that is passed?
-
hakuna matata over 8 yearsWith reflection I can call the method
testChildA
even ifobj
isParent
inParent obj = child.newInstance();
? -
Andy Turner over 8 yearsSure - you can call it - but it doesn't mean that it is guaranteed to work.
Method
is decoupled from the instance that invoke it on. For instance, you could callmethod.invoke("string")
- which will result in a runtime exception. It's up to you to ensure that you only call it in a way that makes sense. -
Andy Turner over 8 yearsWhy bother passing
child
as a parameter then? It helps if you highlight what you have actually changed, rather than just saying "try this block of code without explanation". -
Andy Turner over 8 years
Class<? extends Parent>
constraints it. -
Andy Turner over 8 years
return type.newInstance()
would be simpler. -
Discern over 8 yearsI agree with that sir. Will edit my answer, thanks :)
-
Emanuele Ivaldi over 8 yearsThe alternative would be to check the class of the object and cast it to the correct implementation and call the proper method, it's not flexible,it sucks but it avoids using reflection, did I say it sucks?
-
lance-java almost 7 yearsAgreed, Im just trying to show the usage of
Class.cast(Object)