RFC для класса Java - это набор всех методов, которые могут быть вызваны в ответ на сообщение объекту класса или каким-либо методом в классе. RFC = M + R, где M = количество методов в классе. R = общее количество других методов, непосредственно вызванных из M.
Мы думаем, что C - это .class, а J - это файл .java, для которого нам нужно вычислить RFC.
class J{
a(){}
b(){}
c(){
e1.e();
e1.f();
e1.g();
}
h(){
i.k();
i.j();
}
m(){}
n(){
i.o();
i.p();
i.p();
i.p();
}
}
здесь M = 6 и R = 9 (не беспокойтесь о вызове внутри цикла. Это рассматривается как один вызов)
Вычислить M несложно. Загрузите C с помощью загрузчика классов и используйте отражение, чтобы получить количество методов.
Расчет R не является прямым. Нам нужно посчитать количество вызовов методов из класса. Только первый уровень.
Для вычисления R я должен использовать регулярное выражение. Обычно формат будет (звонки без использования. Не учитываются)
[variable_name].[method_name]([zero or more parameters]);
или же
[variable_name].[method_name]([zero or more parameters])
без точки с запятой, когда возврат вызова напрямую становится параметром другого метода. или же
[variable_name].[method_name]([zero or more parameters]).method2();
это становится двумя вызовами метода
Какие еще шаблоны вызова метода вы можете придумать? Есть ли другой способ, кроме использования RegEx, который можно использовать для вычисления R.
Обновлено:
@McDowell
Похоже, с помощью BCEL я могу упростить весь процесс. Дай мне попробовать.




Вы должны найти свой ответ в Спецификация языка Java.
Вы забыли вызов статического метода, вызов метода внутри параметров ...
Вызов метода с использованием отражения (имя метода в строке).
Вы можете использовать Инженерная библиотека байтового кода с двоичными файлами. Вы можете использовать По убыванию Посетитель для посещения членов и ссылок класса. Я использовал его на найти зависимости классов.
В качестве альтернативы вы можете повторно использовать некоторую модель исходных файлов. Я почти уверен, что редактор Java в Затмение JDT опирается на какую-то модель.
Включает ли M вызовы своих собственных методов? Или звонки во внутренние классы? Например:
class J {
a() { }
b() { this.a(); }
c() { jj.aa(); }
d() { i.k(); }
e() { this.f().a(); }
f() { return this; }
g() { i.m().n(); }
class JJ {
aa() { a(); }
}
}
Каким было бы значение M? Есть только три вызова функций метода, не определенного в этом классе (вызовы в функциях d () и g ()). Вы хотите включить вызовы внутренних классов или вызовы основного класса, сделанные во внутреннем классе? Вы хотите включить вызовы других методов в тот же класс?
Если вы смотрите на любые вызовы методов, независимо от источника, то регулярное выражение, вероятно, могло бы работать, но было бы сложно понять правильно (правильно ли ваше регулярное выражение игнорирует строки, содержащие содержимое, подобное вызову метода? Правильно ли оно обрабатывает вызовы конструктора ?). Если вам важен источник вызова метода, то регулярные выражения, вероятно, не дадут вам то, что вы хотите. Вам нужно будет использовать отражение (хотя, к сожалению, я недостаточно знаю об отражении, чтобы быть полезным).