2013-10-23 48 views
0

问题标题感觉很笨拙。我很感激编辑。
我正在尝试创建一个可重用的查询,以返回由指定的String指定的某种类型对象的List
这不会工作,但我想这将明确什么,我试图做的:如何动态地将某个泛型类型分配给List?

public List<?> getAll(String type) { 
    Class clazz = Class.forName(type); 
    return (List<clazz>) em.createQuery("SELECT t from " + type + " t").getResultList(); 
} 
+2

为什么你没有使用没有泛型的简单列表? – Masudul

+0

由于类型删除,我不认为这是可能的。 – Christian

+0

你需要像列表一样的东西,把你从数据库中获取的数据或类似的东西 –

回答

5

尝试使用该类型的类:

public <T> List<T> getAll(Class<T> type) { 
    return em.createQuery("SELECT t from " + type.getSimpleName() + " t").getResultList(); 
} 

注意,这仍然会产生警告,因为getResultList()返回一个原始列表。

编辑

如果你只有一个完全合格的类名,即你需要调用Class.forName(),有没有办法知道在编译时的类 - 既然泛型(几乎)是一个编译时功能只(提示:类型擦除),他们不会在这种情况下帮助。

你仍然可以调用泛型方法与Class.forName()检索像这样一类:

List<?> l = getAll(Class.forName(typeName)); 

你也可能不需要获取类对象本身,如果它只是一个查询(但是,可能有意义,首先检查该字符串是否是现有类的名称)。在这种情况下,你的方法可能是这样的:

public List<?> getAll(String type) { 
    return em.createQuery("SELECT t from " + type + " t").getResultList(); 
} 

这种变体也将让您无论是传递一个完全合格的类名或实体的名称,即它会在一定程度上更加灵活。

另外,你可以返回List<Object>,这将允许你添加更多的对象到列表中(但要小心,你可以添加任何东西)。

这就是说,我会尽可能使用第一个选项,第二个选项作为回退时,具体类型(或至少某些接口)在编译时未知。

+1

你可以创建'TypedQuery'来代替。 –

+0

如何从'String'获得'Class '? – Lester

+0

@Lester我会更新答案,但是您没有办法直接使用该类而不是类名? – Thomas

相关问题