25

.dexDalvik には、1 つのファイルに含めることができるメソッドの数 (約 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 メソッドの制限に関して、これは 1 つのメソッドの追加と見なされますか、それとも 4 つのメソッドの追加と見なされますか? (または、物事を論理的な結論に導くために、これは 1 つのメソッドまたは 52 のメソッドとしてカウントされますが、それによって 12 のメソッドももたらされると思いjava.lang.Objectます)。

背景として、いくつかの共通点を持つ自明ではない数の生成されたクラスがあり、メソッドの制限にもぶつかっているため、それらのいくつかをクラスに抽象化する価値があるかどうか疑問に思っています時間を稼ぐためのヒエラルキー。

4

1 に答える 1

14

継承されているがオーバーライドされていないメソッドは、それが参照される (呼び出される) 場合にのみ、メソッドの制限に対してカウントされます。

あなたの例では、次のコードがあるとしましょう

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

この場合、明示的な定義により、すでに参照を持っている Foo.foo() を参照しています。これらの 5 つのクラスが dex ファイル内の唯一のクラスであると仮定すると、合計 2 つのメソッド参照* が作成されます。1 つは main.main(String[]) 用、もう 1 つは 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(文字列[])
  • フー.フー()
  • A.foo()
  • B.foo()
  • C.foo()

*この数は正確ではありません。バックグラウンドで各クラスに追加されるコンストラクター メソッドは考慮されていません。各コンストラクターはそのスーパークラスのコンストラクターを呼び出すため、Object コンストラクターへの参照もあり、各ケースで合計 6 つの追加メソッド参照があり、メソッド数はそれぞれ 8 と 11 になります。


疑問がある場合は、さまざまなシナリオを試して、baksmali の raw ダンプ機能を使用して、dex ファイルのメソッド リストに実際に何が含まれているかを確認できます。

例えば

javac *.java
dx --dex --output=temp.dex *.class
baksmali -N -D temp.dump temp.dex

次に、ダンプ ファイルで「method_id_item セクション」を探します。これは、64k 制限が適用されるメソッド参照のリストです。

于 2013-07-18T19:21:00.543 に答える