从JLS§15.2.12.1开始:
- 如果方法调用包括显式类型参数,并且成员是泛型方法,则类型参数的数量等于方法的类型参数的数量。
此子句暗示非泛型方法可能潜在地适用于提供显式类型参数的调用。确实,这可能是适用的。在这种情况下,类型参数将被简单地忽略。
其次是理由
该规则源于兼容性和可替代性原则。由于接口或超类的生成可以独立于其子类型,因此我们可以用非泛型方法覆盖泛型方法。但是,重写(非泛型)方法必须适用于对泛型方法的调用,包括显式传递类型实参的调用。否则,该亚型将无法替代其生成的超型。
按照这一推理,让我们构造一个示例。假设在Java 1.4中,JDK有一个类
public class Foo{ public Object check(Object obj){ ... }}一些用户编写了一个专有类,该类扩展
Foo并覆盖了
check方法
public class MyFoo extends Foo{ public Object check(Object obj){ ... }}当Java 1.5引入泛型时,
Foo.check泛化为
public <T> T check(T obj)
雄心勃勃的向后可比性目标要求
MyFoo仍在Java
1.5中进行编译而无需进行修改。并且
MyFoo.check[Object->Object]仍然是压倒性的方法
Foo.check[T->T]。
现在,根据上述理由,由于可以编译:
MyFoo myFoo = new MyFoo(); ((Foo)myFoo).<String>check("");这也必须编译:
myFoo.<String>check("");即使
MyFoo.check不是通用的。
听起来像是舒展。但是,即使我们支持这种观点,解决方案仍然过于广泛和过分。JLS可能已经向上,以便将其拧紧
myFoo.<String,String>check和
obj.<Blah>toString()是非法的,因为类型参数参数数量不匹配。他们可能没有时间解决问题,所以他们只走了一条简单的路线。



