简体   繁体   中英

Cast an object to class type passed as parameter

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?

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;
}

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.

Try this one.

public class Driver {
    Parent func(Class child, String whichChild) throws Exception {
        // whichChild: "ChildA" or "ChildB"

        child.forName(whichChild);

        Object obj = child.newInstance();
        // cast obj to type of child and call the method "test" + whichChild
    }
}

I doubt it. As far as the compiler concerns, any instance of Class can be sent as parameter.

So, for the compiler, there is no proof that this instance is actually an instance of the type you send along.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM