如何创建类的对象 - 但WHICH类是变化的,并且依赖于其他变量

时间:2016-11-16 21:06:24

标签: java function class object

如果我希望我的程序创建一个类的对象,但是选择哪个类还不确定。我该怎么办?

代码:

for (int i = 1; i < 11; i++) {
    String choice = getChoice(i);
    if (i == 1) {
        obj.add(new choice(w, i)); // the "choice" here is not accepted as a class
        ...etc

getChoice-function看起来像这样:

private String getChoice(int ID) {
    String choice = "Class10"; // It says Class10 now, but in the future
    // the class name will be taken from a database. Hence, the chosen class
    // will be determined by the ID.
    return choice;
}

2 个答案:

答案 0 :(得分:3)

你有时间定义一个体系结构,如果该方法可以返回不同的类,我可以推断这些类是以某种方式相关的,并且有关于它们可以做什么或它们是什么的共同点......

然后,您可以为课程做准备做好准备:

public interface ISomethingInCommon{
    void something();
}

private ISomethingInCommon getChoice(int ID) {
    swith(){
    case 0:
        return new FooA();
    case 1:
        return new FooB();
    defult:
        return new FooDefault();
}

为了有效 FooA FooB FooDefault 必须实施 ISomethingInCommon

答案 1 :(得分:0)

Class.forName()会为您指定class。然后#newInstance()将创建该类的对象。

String choice = getChoice(i);
Class<?> clazz = Class.forName(choice);
Object object = clazz.newInstance();

如果需要将参数传递给构造函数,则需要使用getConstructor(...)

/* Assuming "w" is a String */
Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class);
Object object = constructor.newInstance(w, i);

注意:您需要使用完全限定的类名,例如your.package.name.Class10

虽然这可以回答您的确切问题(根据类的String名称创建对象),但这种方法存在风险。 例如,您指出类名将来自数据库;数据库中的恶意条目可以创建几乎任何类的对象。

如果提前知道所有可能的类,则从getChoice()的所有有效类的集合返回类(不是字符串)会更安全。

根据评论中的课程,如下:

package simulator;

import java.lang.reflect.*;
import java.util.*;

public class Simulator {

    public static void main(String... args)
            throws InstantiationException, IllegalAccessException, NoSuchMethodException,
            SecurityException, IllegalArgumentException, InvocationTargetException {
        for (int i = 0; i < 2; i++) {
            Class<? extends Unit> unit_class = getChoice(i);
            Constructor<? extends Unit> constructor = unit_class.getConstructor(String.class);
            Unit unit = constructor.newInstance("Name");
            System.out.println(unit);
        }
    }

    private final static List<Class<? extends Unit>> UNIT_BY_ID = Arrays.asList(TallMan.class,
            ShortMan.class);

    private static Class<? extends Unit> getChoice(int id) {
        return UNIT_BY_ID.get(id);
    }
}

class Unit {
    Unit(String name) {
    }
}

class Man extends Unit {
    Man(String name) {
        super(name);
    }
}

class TallMan extends Man {
    public TallMan(String name) {
        super(name);
    }
}

class ShortMan extends Man {
    public ShortMan(String name) {
        super(name);
    }
}

输出:

  

simulator.TallMan@15db9742
  simulator.ShortMan@6d06d69c