JAVA 方法参数化_Java如何使用Set参数化泛型方法?

我有一个这样的签名方法:

private Map m(Map data, Class type)

当我这样调用时,它工作正常:

Map abc= null;

m(abc, String.class);

但是当我的参数T是一个Set时它不起作用:

Map> abc= null;

m(abc, Set.class);

有没有办法让它发挥作用?

解决方法:

你将不得不做一些非常难看的事情,使用这样的未经检查的演员:

m(abc, (Class>) (Class>) Set.class);

这归结为类型擦除.在运行时Class< Set< String>>与Class< Set< Integer>>相同,因为我们没有具体的泛型,所以没有办法知道你拥有的是一组“字符串集”与一个类的类“整数集”.

前段时间我问了一个相关的问题,还应该给你一些指示:

国际海事组织的这种混乱是因为仿制药在事后被拴上了,而且没有具体化.当编译器告诉你泛型类型不匹配时,我认为这是语言的失败,但你甚至没有简单的方法来表示特定的类型.例如,在您的情况下,您最终会遇到编译时错误:

m(abc, Set.class);

^

required: Map,Class

found: Map>,Class

reason: inferred type does not conform to equality constraint(s)

inferred: Set

equality constraints(s): Set,Set

where T is a type-variable:

T extends Object declared in method m(Map,Class)

现在,你完全有理由认为“哦,我应该使用Set< String> .class then”,但这不合法.这是语言中泛型实现的抽象泄漏,特别是它们受到类型擦除的影响.从语义上讲,Set< String> .class表示一组字符串的运行时类实例.但实际上在运行时我们无法表示一组字符串的运行时类,因为它与包含任何其他类型的对象的集合无法区分.

因此,我们有一个与编译时语义不一致的运行时语义,并且知道为什么Set< T> .class不合法需要知道泛型在运行时没有被统一.这种不匹配导致了像这样的奇怪的变通方法.

问题的复杂性在于,类实例最终也与类型标记混为一谈.由于您无法在运行时访问泛型参数的类型,因此解决方法是传入Class< T>类型的参数.从表面上看,这非常有用,因为你可以传递像String.class这样的东西(类型为Class< String>)并且编译器很高兴.但是这种方法在你的情况下会崩溃:如果T本身代表一个具有自己的泛型类型参数的类型怎么办?现在使用类作为类型标记是没有用的,因为没有办法区分Class< Set< String>>和类< Set>因为从根本上说,它们在运行时都是Set.class,因此共享同一个类实例.因此,使用类作为运行时类型令牌的IMO不能作为通用解决方案.

由于语言的这个缺点,有一些库使得检索泛型类型信息变得非常容易.此外,他们还提供类更好地表示某事物的“类型”:

标签:java,generics

来源: https://codeday.me/bug/20190519/1136995.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值