我正在尝试生成基于 .smali 文件的调用图。然而,我遇到了一个令人困惑的案例如下:
.super Landroid/graphics/drawable/Drawable;
.source "SBarExp.java"
.method public final setBounds(Landroid/graphics/Rect;)V
.line 514
iget-object v2, p0, Lcom/sds/android/ttpod/app/modules/skin/view/SeekBarExpansion$a;->b:Landroid/graphics/drawable/Drawable;
invoke-virtual {v2, p1, v0, p3, v1}, Landroid/graphics/drawable/Drawable;->setBounds(IIII)V
.line 515
invoke-super {p0, p1, v0, p3, v1}, Landroid/graphics/drawable/Drawable;->setBounds(IIII)V
.end method
根据我的理解,invoke-super
只是意味着它将调用父方法,所以
调用 super {p0, p1, v0, p3, v1}, Landroid/graphics/drawable/Drawable;->setBounds(IIII)V
可以解释为Landroid/graphics/drawable/Drawable;->setBounds(IIII)V
?
如果是,我想知道 invoke-virtual {v2, p1, v0, p3, v1}, Landroid/graphics/drawable/Drawable;->setBounds(IIII)V
是不是与 invoke-super {p0, p1, v0, p3, v1}, Landroid/graphics/drawable/Drawable;->setBounds(IIII)V
相同吗
如果不是,有什么区别?如果是,为什么它两次调用相同的方法(使用不同的方式)?
请帮忙,非常感谢!
最佳答案
invoke-virtual 使用与目标对象的类关联的虚表(即第一个参数的实际运行时类型)执行虚拟表查找。
然而,invoke-super 略有不同。它使用包含正在执行的方法的类的父类(super class)执行 vtable 查找。特别要注意,vtable 查找不使用或依赖于目标对象的运行时类型。
在您的示例中,调用虚拟指令的结果是
iget-object v2, p0, Lcom/sds/android/ttpod/app/modules/skin/view/SeekBarExpansion$a;->b:Landroid/graphics/drawable/Drawable;
此时,实际调用的方法取决于 v2 的实际类型,可以是 Drawable 的任何子类。
在 p0 寄存器上调用 invoke-super 指令,它可能包含当前对象的“this”引用。但是,p0 的运行时类型实际上并不重要。 invoke-super 指令将始终调用 Drawable 的 setBounds 实现,而不管 p0 的运行时类型如何。
关于java - .smali 调用虚拟和调用 super ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23521442/