根据类型创建不同的对象

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

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

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

我愿意接受可能以另一种方式解决我的问题的建议,而不是我想要的。

您可以使用

 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

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

 import java.util.*; class Test { public static void main(String[] args) throws Exception { Map> classes = new HashMap>(); classes.put("object1", Object1.class); classes.put("object2", Object2.class); String type = "object2"; Object obj = classes.get(type).newInstance(); //... } } class Object1 { ... } class Object2 { ... } 
 package main; import java.util.ArrayList; import java.util.List; public class TempClass { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException { List classes = new ArrayList() {{ 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"); } } 

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

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

使用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");