根据类型创建不同的对象

时间:2012-02-07 10:10:43

标签: java android

我有一个包含名为type的列的数据库表。对于我的数据库列中的每一行,我必须根据类型创建一个对象。目前我使用if else语句:

if (type.equals("object1")){
    Object1 object1 = new Object1();
}
else if (type.equals("object2")){
    Object2 object2 = new Object2();
}

使用枚举会更好一些,因为类型的数量是有限的,但是有可能让对象的创建依赖于String的值吗?

我愿意接受可能以另一种方式解决我的问题的建议。

5 个答案:

答案 0 :(得分:3)

您可以创建从StringClass的地图并使用newInstance。然而,这依赖于无参数构造函数的存在。

import java.util.*;

class Test {
    public static void main(String[] args) throws Exception {
        Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
        classes.put("object1", Object1.class);
        classes.put("object2", Object2.class);

        String type = "object2";

        Object obj = classes.get(type).newInstance();

        //...
    }
}

class Object1 { ... }

class Object2 { ... }

答案 1 :(得分:2)

您可以使用

Object o = Class.forName(type).newInstance();

如果你有一个int和两个字符串作为你需要的参数。

Object o = Class.forName(type)
                .getConstructor(int.class, String.class, String.class)
                .newInstance(intValue, string1, string2);

另一种可能性是使用工厂方法

Object o = getClass().getMethod("create_" + type).invoke(null);

static Object1 create_object1() {
     return new Object1(/* with args */);
}

static Object2 create_object2() {
     return new Object2(/* with other args */);
}

但最灵活的方法可能是使用开关

Object o;
switch(type) { // in Java 7
    case "object1": o = new Object1(); break;
    case "object2": o = new Object2(); break;

更优雅的是在Java 8中使用闭包。

http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-final.html

答案 2 :(得分:0)

package main;

import java.util.ArrayList;
import java.util.List;

public class TempClass {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        List<Class> classes = new ArrayList<Class>() {{
            add(Class.forName("main.Object1"));
            add(Class.forName("main.Object2"));
        }};
        for (Class aClass : classes) {
            Object o = aClass.newInstance();
        }
    }
}


package main;

public class Object1 {
    public Object1() {
        System.out.println("Object1");
    }
}


package main;

public class Object2 {
    public Object2() {
        System.out.println("Object2");
    }
}

答案 3 :(得分:0)

使用switchif语句会强制您对各种选项进行硬编码,因此在我看来,您将获得一个不那么灵活的解决方案。

我总是喜欢编写可扩展用于未来软件开发的代码。

因此,我建议您使用Object o = Class.forName(type).newInstance();在数据库中输入要实例化的类的名称,如果需要,还可以使用自定义标签。

修改

如果必须将一些参数传递给必须实例化的类的构造函数,那么使用Constructor.newInstance()代替Class.newInstance();并使用Constructor对象来实例化类很方便,例如:

Class myClass = Class.forName(type);

// get the constructor you need specifying parameters type 
Constructor constructor = myClass.getConstructor(String.class);

Object myObject = constructor.newInstance("constructor-arg");

答案 4 :(得分:0)

如果有问题的类是继承层次结构的一部分,并且您碰巧使用某种映射工具/框架(如Hibernate或iBATIS / MyBatis),它可能包含一种配置所谓的鉴别器的方法。

然后,您可以将“type”列配置为descriminator列,并将支持的值映射到您的类。然后,当您从数据库中检索对象时,框架将为您实例化适当的类。