问题描述
这是我最近在一次采访中提出的一个问题,因为候选人希望看到将其添加到 Java 语言中.Java 没有 reified 泛型通常被认为是一种痛苦 但是,当被推动时,候选人实际上无法告诉我如果他们在那里他可以取得什么样的成就.
This came up as a question I asked in an interview recently as something the candidate wished to see added to the Java language. It's commonly-identified as a pain that Java doesn't have reified generics but, when pushed, the candidate couldn't actually tell me the sort of things that he could have achieved were they there.
显然,因为原始类型在 Java 中是允许的(和不安全检查),所以有可能颠覆泛型并最终得到一个 List
,它(例如)实际上包含 String
s.如果类型信息具体化,这显然是不可能的;但肯定不止这些!
Obviously because raw types are allowable in Java (and unsafe checks), it is possible to subvert generics and end up with a List<Integer>
that (for example) actually contains String
s. This clearly could be rendered impossible were type information reified; but there must be more than this!
人们能否发布他们真正想做的事情的例子,具体化的泛型是否可用?我的意思是,显然你可以在运行时获得 List
的类型 - 但是你会用它做什么?
Could people post examples of things that they would really want to do, were reified generics available? I mean, obviously you could get the type of a List
at runtime - but what would you do with it?
public <T> void foo(List<T> l) {
if (l.getGenericType() == Integer.class) {
//yeah baby! err, what now?
EDIT:对此的快速更新,因为答案似乎主要关注需要传入 Class
作为参数(例如 EnumSet.noneOf(TimeUnit.class)
).我正在寻找更多类似不可能的东西.例如:
EDIT: A quick update to this as the answers seem mainly to be concerned about the need to pass in a Class
as a parameter (for example EnumSet.noneOf(TimeUnit.class)
). I was looking more for something along the lines of where this just isn't possible. For example:
List<?> l1 = api.gimmeAList();
List<?> l2 = api.gimmeAnotherList();
if (l1.getGenericType().isAssignableFrom(l2.getGenericType())) {
l1.addAll(l2); //why on earth would I be doing this anyway?
推荐答案
从我几次遇到这种需求"来看,它最终归结为这个结构:
From the few times that I came across this "need", it ultimately boils down to this construct:
public class Foo<T> {
private T t;
public Foo() {
this.t = new T(); // Help?
}
}
假设 T
有一个 default 构造函数,这在 C# 中确实有效.您甚至可以通过 typeof(T)
获取运行时类型 并通过 Type.GetConstructor() 获取构造函数
.
This does work in C# assuming that T
has a default constructor. You can even get the runtime type by typeof(T)
and get the constructors by Type.GetConstructor()
.
常见的 Java 解决方案是将 Class
作为参数传递.
The common Java solution would be to pass the Class<T>
as argument.
public class Foo<T> {
private T t;
public Foo(Class<T> cls) throws Exception {
this.t = cls.newInstance();
}
}
(不一定需要作为构造函数参数传递,作为方法参数也可以,上面只是一个例子,为了简洁起见省略了try-catch
)
对于所有其他泛型类型构造,可以通过反射的帮助轻松解析实际类型.以下问答说明了用例和可能性:
For all other generic type constructs, the actual type can easily be resolved with a bit help of reflection. The below Q&A illustrate the use cases and possibilities:
这篇关于为什么我要关心 Java 没有具体化的泛型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!