Java: make a function not virtual - call parent method on parent reference
我想这个问题以前就有人问过,但没能立即找到答案。
比如说,某个Pet引用被分配一个Dog对象:
如果我写
号
子类(EDCOX1×1)的方法是通过Java中的所有函数都是虚拟的来调用的。
是否可以调用Pet的attackInvader()?
(我知道我可以编辑Dog的方法来调用super,但在这种情况下,假设我不能更改Dog的实现。)
- 我知道以前有人问过,我会找的…
- D M:好的,谢谢。
- 阿法克,这是不可能的(没有总反射)。
- 你不能,因为Java的设计阻止了你这样做。这是一个安全功能。唯一的方法是,如果您能够修改Dog的方法来调用super()。
- 我能找到的最接近的是stackoverflow.com/questions/13403017/…
- @Andyturner我不同意这是那个特定问题的复制品,即使它几乎肯定是复制品。如果你不能修改Dog的话,super()没有帮助。
- @o.koo感谢您确认这是不可能的。但是你能详细说明为什么这会是一个安全问题吗?
- 谢谢你的链接-这个问题确实很相似。但在我的例子中,如果真的想确保调用基类的方法,可以使用final来确保Pet不被继承…
- java.lang.invoke.MethodHandle提供了一个脆弱的解决方案。您基本上是用Pet.class和Lookup.PRIVATE反射地调用私有MethodHandles.Lookup(Class>, int)构造函数,然后在查找对象上调用findSpecial以获取描述非重写方法的MethodHandle,最后在您的Pet实例(Dog上通过句柄调用它。我相信至少有一个答案证明了这种方法,但目前还找不到。
如果不重写Dog中的方法,也不将实例化对象从Dog更改为Pet中的方法,则不可能实现多态性:在运行时调用的方法始终是运行时对象的方法。现在作为替代方案,您可以在Dog中提供一个方法,将其转换为Pet实例:
1 2 3
| public Pet toPet(){
return new Pet(...);
} |
然后调用attackInvader():
1
| myDog.toPet().attackInvader(); |
号
或者通过在Dog中创建一种提供这种特定行为的新方法:
1 2 3
| public void attackInvaderPet(){
super.attackInvader();
} |