java 类型变量使用通配符后如何调用?
有一个泛型类 A
class A<T extends Person>
{
public void test(T val)
{
val.say();
}
}
然后具有父子关系的普通类:
class Person {
}
class Male extends Person {
public void say()
{
System.out.println("i am male");
}
}
使用通配符代码运行以下代码后,无法执行!这是为什么?
class App {
public static void main(String[] args)
{
// male 实例
Male male = new Male();
// 泛型类 A<Male>
A<Male> maleA = new A<>();
// 泛型类 A<? extends Person>
A<? extends Person> personA = maleA;
// 这个地方为什么报错?
// 我看书中的解释是说 A<? extends Person> 中
// 由于 ? 是通配符,虽然意思表明需要提供的类型
// 为 Person 的子类型,但是由于通配符的原因
// 导致该方法实际上是拒绝任何类型的
// 所以实际上是成了无法调用的方法
// 这是为什么?
personA.test(male);
}
}
使用了 ?
通配符后,即使提供正确的参数也无法成功调用(从代码上看...),这是为什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
学java泛型的时候要抛弃面向对象里面继承那一套东西,始终从类型安全角度来考虑。
思考一下,从编译器的角度来考虑,在这段程序里面,personA的具体泛型类型是什么?
答案是不知道,编译器只知道是Person或其子类型,但无法确定具体类型是什么。所以把male传入test方法是不安全的。
举个例子,如果male允许,那么假设我有一个Female类,同样继承Person,那么下面这段代码:
同样可以通过编译,但这样就违反了设计泛型的初衷,破坏了类型安全性。所以java编译器干脆就拒绝编译这样的代码了
是无法执行还是无法通过编译,泛型不会影响执行,编译成字节码之后,所有调用的参数都会变成Person,调用不可能不成功。
如果编译不能成功,可以强制类型转换。