Dalvik对单个.dex
文件中可以拥有的方法数量有着众所周知的限制(约65,536个)。我的问题是,继承(但未覆盖)的方法是否会计入此限制。
为了使事情具体化,假设我有:
public class Foo {
public int foo() {
return 0;
}
}
public class A extends Foo { }
public class B extends Foo { }
public class C extends Foo { }
出于65,536方法限制的目的,这是否算作添加一个方法,或添加4? (或者,我想,为了得出合乎逻辑的结论,考虑到java.lang.Object
带来了12种方法,这算作1种方法或52种方法)。
作为背景,我有一些非常微不足道的生成类具有一些共性,而且我也遇到了方法限制,所以我想知道是否值得尝试将其中一些抽象出来为了买一些时间,进入一个类层次结构。
答案 0 :(得分:14)
如果被引用(被调用),则继承但未被重写的方法仅计入方法限制。
在您的示例中,假设您有以下代码
public class main {
public static void main(String[] args) {
Foo foo = new A();
foo.foo();
}
}
在这种情况下,由于显式定义,您指的是已经有引用的Foo.foo()。假设这5个类是dex文件中唯一的类,则总共有2个方法引用*。一个用于main.main(String []),另一个用于Foo.foo()。
相反,假设您有以下代码
public class main {
public static void main(String[] args) {
A a = new A();
a.foo();
B b = new B();
b.foo();
C c = new C();
c.foo();
}
}
在这种情况下,由于实际引用了每个子类的foo方法,因此它们将计入您的方法限制。您的dex文件将有5个方法引用*。
* 这个计数不太准确,它没有考虑在幕后添加到每个类的构造函数方法。每个构造函数都调用它的超类'构造函数,所以我们也有一个Object构造函数的引用,在每种情况下总共有6个额外的方法引用,分别给出了8和11的方法计数。
如果有疑问,您可以尝试各种方案并使用baksmali的原始转储功能来查看dex文件中的方法列表实际包含的内容。
e.g。
javac *.java
dx --dex --output=temp.dex *.class
baksmali -N -D temp.dump temp.dex
然后,在转储文件中,查找“method_id_item section”。这是64k限制适用的方法引用列表。