覆盖子类作为参数和泛型:它在Java Lang Spec中的位置?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了覆盖子类作为参数和泛型:它在Java Lang Spec中的位置?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1625字,纯文字阅读大概需要3分钟。
内容图文
我遇到类似以下的Java代码:
public interface BaseArg {
}
public class DerivedArg implements BaseArg {
}
public abstract class Base <A extends BaseArg> {
A arg;
void doIt() {
printArg(arg);
}
void printArg(A a) {
System.out.println("Base: " + a);
}
}
public class Derived extends Base<DerivedArg> {
void printArg(DerivedArg a) {
System.out.println("Derived: " + a);
}
public static void main(String[] args) {
Derived d = new Derived();
d.arg = new DerivedArg();
d.doIt();
}
}
(随意将其拆分为文件并运行它).
此代码最终调用Derived printArg.我意识到这是唯一符合逻辑的事情.但是,如果我手动在通用Base上执行“擦除”,将所有出现的A替换为BaseArg,则覆盖会发生故障.我现在得到Base的printIt版本.
似乎“擦除”不完全 – 不知何故printArg(A a)与printArg(BaseArg a)不同.我在语言规范中找不到任何基础…
我在语言规范中缺少什么?这不是很重要,但它让我烦恼:).
解决方法:
请注意,调用派生方法.问题是为什么,考虑到它们的擦除签名不是覆盖等价的.
编译类Derived时,编译器实际上发出两个方法:方法printArg(DerivedArg)和合成方法printArg(BaseArg),它根据类型参数无法理解的虚拟机来覆盖超类方法,并委托给printArg (DerivedArg).您可以通过在printArt(DerivedArg)中抛出异常,同时在Base类型的引用上调用异常并检查堆栈跟踪来验证这一点:
Exception in thread "main" java.lang.RuntimeException
at Derived.printArg(Test.java:28)
at Derived.printArg(Test.java:1) << synthetic
at Base.doIt(Test.java:14)
at Test.main(Test.java:39)
至于在Java语言规范中找到这个,我首先也错过了它,因为它不是,正如人们所预料的那样,指定了覆盖或子签名关系的讨论,而是在“参数化类型的成员和构造函数”(§4.5.2)中,揭示了在检查重写等价之前,超类的形式类型参数在语法上被子类中的实际类型参数替换.
也就是说,与普遍的假设相反,覆盖等价不受擦除的影响.
内容总结
以上是互联网集市为您收集整理的覆盖子类作为参数和泛型:它在Java Lang Spec中的位置?全部内容,希望文章能够帮你解决覆盖子类作为参数和泛型:它在Java Lang Spec中的位置?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。