2017-01-14 13 views
3

Я пытаюсь создать метод, который сравнивает параметры 2 методов и дать мне процент соответствующих параметров, как:Сравнивая ASM MethodNode параметры

Method1(int i, boolean b, char c)  
Method2(boolean b, int i) 
Method3(char c)  
Method4(double d) 


Method1 and Method2 = 66% -> 2 matching parameters  
Method1 and Method3 = 33% -> 1 matching parameter 
Method1 and Method4 = 0% -> 0 matching parameters 

Может кто-нибудь дать мне подсказку, как это сделать ?

+0

выглядит скорее как вопрос для компилятора, чем для программы Java , Насколько я знаю, Fromw в рамках программы вы не можете проверять методы. –

ответ

3

Обновлено советы Holger в

private static float compare(MethodNode mn1, MethodNode mn2) { 
    Type[] typeArgs1 = Type.getArgumentTypes(mn1.desc); 
    Type[] typeArgs2 = Type.getArgumentTypes(mn2.desc); 
    int max = Math.max(typeArgs1.length, typeArgs2.length); 
    if (max == 0) 
     return 1f; 
    int matches = 0; 
    List<Type> types = Arrays.asList(typeArgs1); 
    for (Type arg : typeArgs2) 
     if (types.contains(arg)) 
      matches++; 
    return ((float) matches/max); 
} 

Оригинальный код:

private static float compare(MethodNode mn1, MethodNode mn2) { 
    Type t1 = Type.getMethodType(mn1.desc); 
    Type t2 = Type.getMethodType(mn2.desc); 
    Type[] targs1 = t1.getArgumentTypes(); 
    Type[] targs2 = t2.getArgumentTypes(); 
    int max = Math.max(targs1.length, targs2.length); 
    int matches = 0; 
    if (max == 0) 
     return 1f; 
    List<String> types1 = new ArrayList<String>(); 
    for (Type t : targs1) 
     types1.add(t.getDescriptor()); 
    for (Type t : targs2) 
     if (types1.contains(t.getDescriptor())) 
      matches++; 
    return (1F * matches/max); 
} 

Выход для примера методы:

0,1 0.0 
0,2 0.0 
0,3 0.0 
0,4 0.0 
1,2 0.6666667 
1,3 0.33333334 
1,4 0.0 
2,3 0.0 
2,4 0.0 
3,4 0.0 
+1

Было бы разумнее объявить 'types1' как' Set' (используя, например, 'HashSet'). Кроме того, при умножении на '1F' запутывается фактическое намерение сделать простое преобразование из' int' в 'float'. Просто используйте тип cast, '(float) match' вместо этого. Обратите внимание, что вы можете упростить свой код, вы можете просто использовать ['Type.getArgumentTypes (desc)'] (http://asm.ow2.org/asm50/javadoc/user/org/objectweb/asm/Type.html#getArgumentTypes -java.lang.String-) без обхода через 'Type.getMethodType'. Вы также можете использовать тот факт, что 'Type' уже реализует' equals' и 'hashCode', поэтому вам не нужен' getDescriptor() ' – Holger

+0

. Я обновил фрагмент предложениями, кроме использования HashSet. Вместо этого я использовал 'Arrays.asList' snce, он вложил дополнительные две строки. Дополнительный шаг 'new HashSet (Arrays.asList (typeArgs1));' для создания 'Set ' кажется ненужным. –

+0

Кажется честным. Количество типов параметров обычно очень мало и ограничено «255» в любом случае, поэтому облегченная оболочка «Arrays.toList» будет работать лучше, чем копирование в «HashSet» в большинстве случаев. Но учтите, что у вас есть дублирование кода; вы вызываете 'Type.getArgumentTypes (mn2.desc)' дважды вместо переменной 'typeArgs2'. – Holger