[英]Java Generic List<>
我正在尝试做这样的事情:
1.方法
Type ty = entityType.getEntityClass(); // could be e.g. String.class
List<ty> list;
2.方法
Class cl = entityType.getEntityClass(); // could be e.g. String.class
List<cl> list;
但是,编译器只是说“ no”。
是否只有通过使用String.class
或foo.getClass()
java.util.List动态的泛型类型<T>
?
...
我实际上想做的是通过EntityTypeEnum
类型或其Class
属性值的给定参数初始化List。
public enum EntityTypeEnum {
ARTICLE(Article.class),
ORDER(OrderHeader.class),
CUSTOMER(Customer.class),
CUSTOMER_SESSION(CustomerSession.class);
private final Class entityClass;
private EntityTypeEnum(final Class entityClass) {
this.entityClass = entityClass;
}
public Class getEntityClass() {
return entityClass;
}
}
欢迎进行建设性的批评。 谢谢!
添加:(作为安迪评论的回应)
Class cl = String.class;
List<cl> list;
..也不工作!
List<String> list;
..作品,当然。
那么String
和String.class
之间的区别是什么?
或者有没有办法像这样设置值:
public enum EntityTypeEnum {
ARTICLE(Article)
..
你是误会什么Java泛型有能力的:你不能这样做基于变量的值的东西,只与变量的类型 。
基本上,Java泛型只是强制转换的一部分:编译器会自动为您插入强制转换,并检查由这些强制转换产生的类型是否匹配。
您可以执行示例中描述的操作,只是不使用枚举。 Java枚举的缺点之一是所有元素都具有相同的类型。
除了使用真实的枚举,还可以使用大致像枚举的形式:
final class EntityTypeEnumIsh {
private EntityTypeEnumIsh() {}
static final EntityClassSupplier<Article> ARTICLE =
new EntityClassSupplier<>(Article.class);
static final EntityClassSupplier<OrderHeader> ORDER =
new EntityClassSupplier<>(OrderHeader.class);
// ...
final class EntityClassSupplier<T> {
private final Class<T> clazz;
EntityClassSupplier(Class<T> clazz) { this.clazz = clazz; }
Class<T> getEntityClass() { return clazz; }
}
}
您现在可以在描述的方法中使用它们:
<T> List<T> method(EntityClassSupplier<T> supplier) {
return new ArrayList<>();
}
并像这样调用:
List<Article> list = method(EntityTypeEnumIsh.ARTICLE);
当然,您无法获得“真实”枚举的全部优点(例如序列化,抵抗反射攻击等)。 但是您会得到其他有用的信息,因此请权衡一下您的用例。
它不起作用,因为泛型是编译时概念,但是您尝试将其用作运行时概念。
区别在于,对于编译时概念,编译器需要能够根据代码中包含的信息(即,无需运行或评估)来确定类型。
此代码在语法上将是正确的:
public enum EntityTypeEnum
{
ARTICLE(String.class), // just using some builtin types to demonstrate
ORDER(Integer.class),
CUSTOMER(Double.class),
CUSTOMER_SESSION(Short.class);
private final Class<?> entityClass;
private EntityTypeEnum(final Class<?> entityClass)
{
this.entityClass = entityClass;
}
public Class<?> getEntityClass()
{
return this.entityClass;
}
}
class Test
{
// here, T is the type parameter which is determined from the class type
public <T> List<T> createList(final Class<T> clazz)
{
return new ArrayList<T>();
}
// this is the demo code on how to use it
public void foo()
{
EntityTypeEnum t = EntityTypeEnum.ARTICLE;
List<?> list = createList(t.getEntityClass());
}
}
问题在于这对您没有太大帮助。 List与List大致相同。 编译器无法将类型缩小到特定的包含对象类,因为它取决于运行时。
对于您的情况,如果您的元素具有通用的超类,则可以使用以下信息来缩小类型的范围:
public enum EntityTypeEnum
{
ARTICLE(Article.class),
ORDER(OrderHeader.class),
CUSTOMER(Customer.class),
CUSTOMER_SESSION(CustomerSession.class);
private final Class<? extends CommonParent> entityClass;
private EntityTypeEnum(final Class<? extends CommonParent> entityClass)
{
this.entityClass = entityClass;
}
public Class<? extends CommonParent> getEntityClass()
{
return this.entityClass;
}
}
class Test
{
public <T extends CommonParent> List<T> createList(final Class<T> clazz)
{
return new ArrayList<T>();
}
public void foo()
{
EntityTypeEnum t = EntityTypeEnum.ARTICLE;
List<? extends CommonParent> list = createList(t.getEntityClass());
}
}
但是,如果您有一个共同的父母,那么上面的代码比编写代码没有任何好处:
List<CommonParent> list = new ArrayList<CommonParent>();
并跳过所有其他通用内容...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.