2015-10-23 83 views
1

我有几个类,比如说MyClassA MyClassB MyClassC和MyClassD如何创建“动态(在运行时决定)”类的实例?

我想要一个函数,如果Class类型会创建(以及做任何..)一个对象,它是类的一个实例。

所以我的功能是这样的,

public void foo(ClassType MyChoosenClassType){ 
     MyChoosenClassType x=new MyChoosenClassType(); 
     //do whatever with x 
} 

有没有一种方法,我可以做到这一点?

或者我将不得不手动使用条件和我自己的方式吗?

+0

这些类是否共享一个通用接口? –

+0

不,但它们是从同一个类扩展而来,比如MyClassParent – SadeepDarshana

+0

这些类的构造函数是什么? –

回答

1

您可以用Java反射API做到这一点,利用Class.getConstructor()Constructor.newInstance()方法:

public <T extends MyClassParent> void foo(Class<T> classType) throws Exception { 
    T instance = (T) classType.getConstructor().newInstance(); // no-args constructor assumed 

    // work with instance, which is a subclass of MyClassParent 
} 

这个工作,只要MyClassParent所有子类有一个无参数的构造函数。如果它们都有另一个构造函数,则可以将期望参数的类传递给Class.getConstructor(),并将实际参数值传递给Constructor.newInstance()。有关更多详细信息,请参阅文档。

然而,与Java 8,你能避免使用反射:

Map<String, Supplier<? extends MyClassParent>> facotries = new HashMap<>(); 

factories.put("MyChosenClassType1", MyChosenClassType1::new); 
factories.put("MyChosenClassType2", MyChosenClassType2::new); 
// etc 

然后,可以按如下方式实现你foo方法:

public void foo(String classType) { 
    Supplier<? extends MyClassParent> factory = factories.get(classType); 
    if (factory != null) { 
     MyClassParent instance = factory.get(); 

     // work with instance 
    } 
} 
+0

你也可以在早期版本的Java中做工厂的事情(避免反思) ;没有':: new' lambda表达式就没有这么简洁。 – Wyzard

+0

我仍然怀疑是否有一种方法如我的示例代码中那样优雅和直接。使用或gererics可以做到这一点吗? – SadeepDarshana

+0

是反映不好? – SadeepDarshana

0

我不知道是否有方式来做我刚才提到的问题;然而,这是我终于想出的解决方案。不像我在示例代码中提到的那样简单直接。 正如Jimmy T.提到的

public void foo(Object anyObjectOfTypeMyClass){ 
     Object x=anyObjectOfTypeMyClass.getClass().newInstance(); 
     //do anything with x 
} 
+0

但是你已经有了这个实例!为什么要创造另一个? –

相关问题