Java 在Android中,继承的方法是否计入Dex方法限制?

Java 在Android中,继承的方法是否计入Dex方法限制?,java,android,dalvik,dex,Java,Android,Dalvik,Dex,Dalvik在一个.dex文件中可以使用的方法数量上有一个众所周知的限制(大约65536个)。我的问题是继承(但不是重写)方法是否符合此限制 为了使事情具体化,假设我有: public class Foo { public int foo() { return 0; } } public class A extends Foo { } public class B extends Foo { } public class C extends Foo { } 就65536方法限

Dalvik在一个
.dex
文件中可以使用的方法数量上有一个众所周知的限制(大约65536个)。我的问题是继承(但不是重写)方法是否符合此限制

为了使事情具体化,假设我有:

public class Foo {
  public int foo() {
    return 0;
  }
}

public class A extends Foo { }
public class B extends Foo { }
public class C extends Foo { }
就65536方法限制而言,这算是添加一种方法还是添加4种方法?(或者,我想,从逻辑上来说,考虑到
java.lang.Object
也带来了12种方法,这算是1种方法还是52种方法)


作为背景,我已经生成了大量具有一些共性的类,我也遇到了方法的限制,因此,我想知道是否值得尝试将其中一些抽象到类层次结构中以争取时间。

继承但未重写的方法只有在被引用(调用)时才计入方法限制

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

public class main {
    public static void main(String[] args) {
        Foo foo = new A();
        foo.foo();
    }
}
在本例中,您引用的是Foo.Foo(),由于显式定义,它已经有一个引用。假设这5个类是dex文件中唯一的类,那么您总共有2个方法引用*。一个用于main.main(字符串[]),一个用于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个方法引用*

  • main.main(字符串[])
  • Foo.Foo()
  • A.傅()
  • B.foo()
  • C.foo()
*这个计数不是很准确,它没有考虑在幕后添加到每个类的构造函数方法。每个构造函数调用其超类的构造函数,因此我们也有一个对对象构造函数的引用,在每种情况下总共有6个额外的方法引用,分别给出8和11个方法计数


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

e、 g


然后,在转储文件中查找“method\u id\u item section”。这是64k限制适用的方法引用列表。

因为您可以更改方法的可见性,所以需要对所有方法进行计数,这难道没有意义吗。retrodev链接到了一个过时的dex文件格式预发布版本的逆向工程。请在dex格式上尝试更权威和最新的source.404。html@JonShemitz:只需从URL栏中删除尾随的
。他应该在那里加个地方。酷-谢谢。构造函数也算方法引用吗?那么这不会增加示例中方法引用的数量吗?@nvrmnd,是的。这是一个很好的观点。我会相应地更新答案。谢谢那么文件或JNI代码中的方法有没有达到这个极限?从dex的角度来看,JNI方法没有什么特别之处,只是它有“本机”访问标志,并且没有实现。因此,是的,dex文件中的方法id列表包括dex文件中声明(或调用)的所有jni方法。
javac *.java
dx --dex --output=temp.dex *.class
baksmali -N -D temp.dump temp.dex