java泛型接口_类-Java泛型-使泛型扩展2个接口

Reimeus已经指出,您在编辑中要求的内容是不可能的。 我只想扩展一下原因。

有人会认为您可以使用以下内容:

public void mapThis(

Class extends MyClass> key,

Class extends U> value

) { ... }

实际上,这就是我第一次看到这篇文章时想到的。 但这实际上会导致编译器错误:

类型变量不能跟其他界限

为了帮助我解释原因,我想引用Victor Rudometov的Oracle Blogs帖子中的错误提示:

这个事实并不总是很清楚,但确实如此。 以下代码 不应编译:

>

>

>

因为JLS第4章 “类型,值和变量”部分4.4类型变量指出:“ bound由类型变量或类或接口类型组成 T可能后面跟着其他接口类型I1,...,In。”。 可以使用T扩展U,T扩展SomeClass&I,但不可以T扩展U&I。 此规则适用于所有情况,包括类型变量和 方法和构造函数。

在一个密切相关的文章中探讨了这种限制的原因:为什么我不能在具有多个界限的类型参数中使用类型参数?

总而言之,施加此限制是为了“避免某些尴尬的情况出现”(JLS§4.9)。

什么样的尴尬情况? 克里斯·波维尔克(Chris Povirk)的回答描述了一个:

[限制的原因是]指定非法类型的可能性。 具体来说,使用不同的参数两次扩展通用接口。 我无法提出一个非人为的示例,但是:

>

现在>是S&T和S&Comparable

克里斯还指出了Sun bug 4899305,它是与该语言限制相抗衡的bug。 由于无法修复,已关闭,并带有以下注释:

如果类型变量后面可以跟类型变量或(可能 参数化)接口,则相互之间可能会更多 递归类型变量,很难处理。 东西 当边界仅仅是参数化类型时,已经很复杂了, 例如 >.因此,界限不会继续 现在改变。 javac和Eclipse都同意S&T和 S&Comparable是非法的。

因此,这就是限制的背后原因。 我要特别指出泛型方法(您的问题所涉及的问题),我还要进一步指出,类型推断理论上将导致这种界限毫无意义。

如果我们重新检查以上假设签名中声明的类型参数:

假设呼叫者未明确指定MyClass.foo("asdf", 42)和Object,可以将其简化为以下内容:

或者只是这个(细微的差别,但这是另一个主题):

这是因为MyClass.foo("asdf", 42)没有任何界限,所以无论传入哪种类型的参数,Object都可以始终至少解析为mapThis,然后U也可以。

让我们回过头说MyClass.foo("asdf", 42)是有界的:

可以用相同的方式减少它(MyClass.foo("asdf", 42)可以是类或接口):

基于这种推理,就将调用方限制为更特定的参数而言,您要尝试实现的语法毫无意义。

Java 8之前的附录:

在Java 8之前,您正在尝试使用一个用例。 由于编译器如何推断通用方法类型参数的限制,我的上述推理是不合时宜的。 采用以下通用方法:

class MyClass {

static void foo(T t1, T t2) { }

}

这是尝试制作一个采用两个“相同类型”参数的方法的常见初学者错误。 当然,由于继承的方式,这毫无意义:

MyClass.foo("asdf", 42); // legal

在这里,MyClass.foo("asdf", 42)推断为Object-这与简化mapThis类型参数的先前推理相吻合。 您必须手动指定类型参数以实现预期的类型检查:

MyClass.foo("asdf", 42); // compiler error

但是,这是您的用例开始出现的地方,带有交错边界的多个类型参数是另一回事:

class MyClass {

static void foo(T t, U u) { }

}

现在,此调用错误:

MyClass.foo("asdf", 42); // compiler error

表已经翻转了-我们必须手动放松类型参数才能进行编译:

MyClass.foo("asdf", 42); // legal

发生这种情况是因为编译器推断方法类型参数的方式有限。 因此,您想要实现的目标实际上是在限制调用者参数的应用程序。

但是,此问题似乎已在Java 8中解决,并且MyClass.foo("asdf", 42)现在可以编译而没有任何错误(感谢Regent指出了这一点)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值