继承的方法是否依赖于Android中的Dex方法限制?

Adr*_*scu 25 java android dalvik dex

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 { }
Run Code Online (Sandbox Code Playgroud)

出于65,536方法限制的目的,这是否算作添加一个方法,或添加4?(或者,我想,为了得到合乎逻辑的结论,这算作1种方法还是52种方法,考虑到这也java.lang.Object带来了12种方法).

作为背景,我有一些非常微不足道的生成类具有一些共性,我也遇到了方法限制,所以我想知道是否值得尝试将其中的一些抽象为类等级为了买一些时间.

Jes*_*eke 14

如果被引用(调用),则继承但未重写的方法仅计算方法限制.

在您的示例中,假设您有以下代码段

public class main {
    public static void main(String[] args) {
        Foo foo = new A();
        foo.foo();
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,由于显式定义,您指的是已经有引用的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,由于实际引用了每个子类的foo方法,因此它们将计入方法限制.您的dex文件将有5个方法引用*.

  • main.main(字符串[])
  • Foo.foo()
  • A.foo()
  • B.foo()
  • C.foo()

*此计数不太准确,它没有考虑在幕后添加到每个类的构造函数方法.每个构造函数都调用其超类的构造函数,因此我们还引用了Object构造函数,在每种情况下总共有6个额外的方法引用,分别给出了方法计数8和11.


如果有疑问,您可以尝试各种方案并使用baksmali的原始转储功能来查看dex文件中的方法列表实际包含的内容.

例如

javac *.java
dx --dex --output=temp.dex *.class
baksmali -N -D temp.dump temp.dex
Run Code Online (Sandbox Code Playgroud)

然后,在转储文件中,查找"method_id_item section".这是64k限制适用的方法引用列表.

  • 构造函数也不算作方法引用吗?那么不会增加示例中方法引用的数量吗? (2认同)