Ответ 1
Унаследованный, но не переопределенный метод учитывает только предел метода, если он когда-либо ссылается (называется).
В вашем примере предположим, что у вас есть следующий фрагмент кода
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 ссылок на методы *.
- main.main(String [])
- Foo.foo()
- A.foo()
- B.foo()
- C.foo()
* Этот счет не совсем точен, он не учитывает методы конструктора, которые добавляются в каждый класс за кулисами. Каждый конструктор вызывает свой конструктор суперкласса, поэтому мы также имеем ссылку на конструктор Object, в общей сложности 6 дополнительных ссылок на методы в каждом случае, давая количество меток 8 и 11 соответственно.
Если вы сомневаетесь, вы можете попробовать различные сценарии и использовать функциональность baksmali raw dump, чтобы увидеть, что на самом деле содержит список методов в файле dex.
например.
javac *.java
dx --dex --output=temp.dex *.class
baksmali -N -D temp.dump temp.dex
И затем в файле дампа найдите "раздел method_id_item". Это список ссылок на методы, к которым применяется ограничение 64k.