简体   繁体   English

如何动态地将某个通用类型分配给列表?

[英]How to dynamically assign a certain generic type to a List?

The question title feels quite clumsy. 问题标题显得很笨拙。 I am grateful for an edit. 感谢您的编辑。
I am trying to create a reusable query to return a List of objects of a certain kind that is specified by an assigned String . 我试图创建一个可重用的查询,以返回由分配的String指定的某种类型的对象的List
This won't work but I suppose it will make clear what I am trying to do: 这是行不通的,但我想它会弄清楚我要做什么:

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

Try using the type's class: 尝试使用类型的类:

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

Note that this will still generate a warning, since getResultList() returns a raw list. 请注意,由于getResultList()返回原始列表,因此仍然会生成警告。

Edit : 编辑

If you only have a fully qualified class name, ie you need to call Class.forName() , there's no way to know the class at compile time - and since generics (almost) are a compile time feature only (hint: type erasure) they won't help in that case. 如果您只有一个完全合格的类名,即您需要调用Class.forName() ,则无法在编译时知道该类-而且由于泛型(几乎)仅是编译时功能(提示:类型擦除)在这种情况下,他们将无济于事。

You could still call the generic method with a class retrieved by Class.forName() like this: 您仍然可以使用Class.forName()检索的类来调用通用方法,如下所示:

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

You might also not need to get the class object itself, if it is just for the query (however, it might make sense to first check that the string is the name of an existing class). 如果仅用于查询,则可能也不需要获取类对象本身(但是,首先检查字符串是否为现有类的名称可能很有意义)。 In this case your method might look like this: 在这种情况下,您的方法可能如下所示:

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

This variant would also allow you to either pass in a fully qualified class name or an entity name, ie it would be somewhat more flexible. 这种变体还允许您传递完全限定的类名或实体名,即它会稍微灵活一些。

Alternatively you could return List<Object> , which would allow you to add further objects to the list (but beware, you could add anything). 或者,您可以返回List<Object> ,这将允许您向列表中添加其他对象(但是请注意,您可以添加任何内容)。

That being said, I'd use the first option whenever possible and the second option as a fallback when the concrete type (or at least some interface) is unknown at compile time. 话虽这么说,但在编译时未知具体类型(或至少某些接口)的情况下,我会尽可能使用第一个选项,并使用第二个选项作为备用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM