为什么我应该关心Java没有具体化的泛型? [英] Why should I care that Java doesn't have reified generics?

查看:145
本文介绍了为什么我应该关心Java没有具体化的泛型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我在一次采访中问道,这是一个候选人希望添加到Java语言中的问题。 Java通常被认为是一种痛苦,它没有泛化的泛型但是,当被推动时候,候选人实际上并不能告诉我他在那里可以取得的成绩。



很明显,因为原始类型是(不安全检查)中允许的,可以颠覆泛型,最终得到一个 List< Integer> (例如)实际上包含秒。如果类型信息具体化,这显然是不可能的;

可以让人发布他们真正想要做的事情的示例 ,是否可以使用泛化的泛型?我的意思是,显然你可以在运行时得到一个 List 的类型 - 但是你会怎么做?

  public< T> void foo(List< T> l){
if(l.getGenericType()== Integer.class){
//是啊宝贝!呃,现在呢?

编辑:快速更新此答案似乎主要是关注需要传入 Class 作为参数(例如 EnumSet.noneOf(TimeUnit.class)) 。我正在寻找更多符合 的行。例如:

 列表<?> l1 = api.gimmeAList(); 
列表<?> l2 = api.gimmeAnotherList();

if(l1.getGenericType()。isAssignableFrom(l2.getGenericType())){
l1.addAll(l2); //为什么我会这样做呢?


解决方案

,它最终归结为这种结构:

  public class Foo< T> {

private T t;

public Foo(){
this.t = new T(); // 帮帮我?
}

}

T 有一个默认的构造函数。你甚至可以通过 typeof(T) 并通过 <$获取构造函数c $ c> Type.GetConstructor()



常见的Java解决方案是传递 Class 作为参数。

  public class Foo< T> {

private T t;
$ b $ public Foo(Class< T> cls)抛出Exception {
this.t = cls.newInstance();
}

}

一定需要作为构造函数参数传递,因为方法参数也很好,以上只是一个例子,为简洁起见, try-catch 也被省略) b
$ b

对于所有其他泛型类型的构造,实际类型可以通过反射帮助轻松解决。下面的Q& A说明了用例和可能性:


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.

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 Strings. This clearly could be rendered impossible were type information reified; but there must be more than this!

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: 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?
    }

}

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().

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();
    }

}

(it does not necessarily need to be passed as constructor argument, as a method argument is also fine, the above is just an example, also the try-catch is omitted for brevity)

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没有具体化的泛型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆