我为什么要关心Java没有经过仿制药?(Why should I care that Java doesn't have reified generics?)

编程入门 行业动态 更新时间:2024-10-25 19:31:02
我为什么要关心Java没有经过仿制药?(Why should I care that Java doesn't have reified generics?)

这是我最近在接受采访时提出的一个问题,作为候选人希望看到的添加到Java语言的问题。 这通常被认为是一种痛苦,Java没有修饰泛型,但是当被推动时,候选人实际上不能告诉我他们可能实现的那些事情。

显然,由于Java中允许使用原始类型(和不安全的检查),因此可以颠覆泛型并最终得到一个List<Integer> ( List<Integer> ,其中(例如)实际上包含String 。 这种明显的可能是类型信息被证明是不可能的; 但是一定有更多的

人们可以发表他们真正想要做的事情的例子, 是否被提供了泛型? 我的意思是,显然你可以在运行时得到一个List的类型 - 但是你会怎么做?

public <T> void foo(List<T> l) { if (l.getGenericType() == Integer.class) { //yeah baby! err, what now?

编辑 :快速更新,因为答案主要是关心需要传递一个Class作为参数(例如EnumSet.noneOf(TimeUnit.class) ))。 我正在寻找更多的东西沿着这一切是不可能的 。 例如:

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?

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?

最满意答案

从我遇到这个“需要”的几次,它最终归结为这个结构:

public class Foo<T> { private T t; public Foo() { this.t = new T(); // Help? } }

这在C#中工作,假设T有一个默认构造函数。 您甚至可以通过typeof(T)获取运行时类型,并通过Type.GetConstructor()获取构造函数。

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

public class Foo<T> { private T t; public Foo(Class<T> cls) throws Exception { this.t = cls.newInstance(); } }

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

对于所有其他通用类型的构造,实际的类型可以很容易地通过反思帮助来解决。 以下Q&A说明了用例和可能性:

获取java.util.List的通用类型 如何在运行时获取通用类型? 在抽象超类上获取实际类型的泛型参数

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:

Get generic type of java.util.List How to get the generic type at runtime? Get actual type of generic type argument on abstract superclass

更多推荐

本文发布于:2023-07-30 07:56:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1336735.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:我为   Java   care   reified   generics

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!