java中方法的具体化_我为什么要关心Java没有具体化的泛型?

问题

这是我最近在一次采访中提出的一个问题,即候选人希望看到添加到Java语言中的问题。它通常被认为是Java没有的痛苦reified generics但是,当被推动时,候选人实际上无法告诉我他在那里可能取得的那些事情。

显然因为Java中允许使用原始类型(以及不安全的检查),所以可以颠覆泛型并最终得到(例如)实际包含537777662的aList。如果确定了类型信息,这显然是不可能的;但必须有更多!

人们可以发布他们真正想要做的事情的例子,他们真正想要做的事情是**,是否可以使用具体的仿制品?我的意思是,显然你可以获得aListat运行时的类型 - 但是你会用它做什么?

public void foo(List l) {

if (l.getGenericType() == Integer.class) {

//yeah baby! err, what now?

编辑:对此的快速更新,因为答案似乎主要是关注需要传递aClass作为参数(例如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?

#1 热门回答(97 赞)

最常引诱我的是无法利用多个泛型类型的多个调度。以下是不可能的,并且在许多情况下它将是最佳解决方案:

public void my_method(List input) { ... }

public void my_method(List input) { ... }

#2 热门回答(80 赞)

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

public class Foo {

private T t;

public Foo() {

this.t = new T(); // Help?

}

}

这在C#中有效,假设T具有adefaultconstructor。你甚至可以通过typeof(T)获取运行时类型,并通过Type.GetConstructor()获取构造函数。

常见的Java解决方案是传递Classas参数。

public class Foo {

private T t;

public Foo(Class cls) throws Exception {

this.t = cls.newInstance();

}

}

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

对于所有其他泛型类型构造,可以通过一些反射帮助轻松解析实际类型。以下问答说明了用例和可能性:

获取java.util.List的泛型类型

如何在运行时获取泛型类型?

在抽象超类上获取实际类型的泛型类型参数

#3 热门回答(33 赞)

类型安全记住了。如果没有具体的泛型,向下转换为参数化类型将始终是不安全的:

List myFriends = new ArrayList();

myFriends.add("Alice");

getSession().put("friends", myFriends);

// later, elsewhere

List myFriends = (List) getSession().get("friends");

myFriends.add(new Friend("Bob")); // works like a charm!

// and so...

List myFriends = (List) getSession().get("friends");

for (String friend : myFriends) print(friend); // ClassCastException, wtf!?

此外,抽象将泄漏更少-至少可能对其类型参数的运行时信息感兴趣的那些。今天,如果你需要有关其中一个通用参数类型的任何类型的运行时信息,你也必须通过其Class。这样,你的外部接口取决于你的实现(无论你是否使用RTTI关于你的参数)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值