2011-05-17 1 views

Répondre

2

Problème intéressant. Probablement un certain nombre d'outils pour faire quelque chose de similaire, mais pas exactement ce que vous voulez. Certes, il y aurait une mise en œuvre facile avec ASM. Comme il est, j'ai fouetté un en utilisant la réflexion:

public class C { 
    public static void main(String[] args) throws java.io.IOException { 
     java.util.jar.JarFile jar = new java.util.jar.JarFile(args[0]); 
     java.util.Enumeration<java.util.jar.JarEntry> jarEntries = jar.entries(); 
     while (jarEntries.hasMoreElements()) { 
      java.util.jar.JarEntry jarEntry = jarEntries.nextElement(); 
      String jarEntryName = jarEntry.getName(); 
      if (!jarEntryName.endsWith(".class")) { 
       continue; 
      } 
      int jarEntryNameSuffixIndex = jarEntryName.length() - 6; 
      String binaryName = jarEntryName.substring(0, jarEntryNameSuffixIndex).replaceAll("/", "\\."); 
      Class<?> type = null; 
      while (type == null) { 
       try { 
        type = ClassLoader.getSystemClassLoader().loadClass(binaryName); 
       } catch (ClassNotFoundException e) { 
        int binaryNameQualifiedIndex = binaryName.indexOf("."); 
        if (binaryNameQualifiedIndex == -1) { 
         throw new RuntimeException("couldn't load class for " + jarEntryName); 
        } else { 
         binaryName = binaryName.substring(binaryNameQualifiedIndex + 1); 
        } 
       } 
      } 
      int typeModifiers = type.getModifiers(); 
      if (!(java.lang.reflect.Modifier.isPublic(typeModifiers) || java.lang.reflect.Modifier.isProtected(typeModi$ 
       continue; 
      } 
      String packageName = (type.getPackage() == null) ? "" : type.getPackage().getName(); 
      String typeName = type.getCanonicalName(); 
      for (java.lang.reflect.Method method : type.getDeclaredMethods()) { 
       if (method.isSynthetic() || method.isBridge()) { 
        continue; 
       } 
       int methodModifiers = method.getModifiers(); 
       if (!(java.lang.reflect.Modifier.isPublic(methodModifiers) || java.lang.reflect.Modifier.isProtected(me$ 
        continue; 
       } 
       String methodName = method.getName(); 
       System.out.print(packageName + ", " + typeName + ", " + methodName + ", "); 
       for (Class<?> parameterType : method.getParameterTypes()) { 
        String parameterTypeName = parameterType.getCanonicalName(); 
        System.out.print(":" + parameterTypeName + ", "); 
       } 
       Class<?> returnType = method.getReturnType(); 
       String returnTypeName = returnType.getCanonicalName(); 
       System.out.println(returnTypeName); 
      } 
     } 
    } 
} 

Inclure le JAR (et ses dépendances) dans le chemin de classe. Cela n'imprimera pas les noms des paramètres, car vous ne pouvez pas les obtenir par réflexion. Il n'affiche pas non plus les paramètres de type ou var-args, bien que vous puissiez les obtenir.

+0

solution très agréable, même si je préférerais que la fonctionnalité a été divisée en plusieurs méthodes différentes. Mais vous faites tout comme je l'aurais fait moi-même (+1) –

+0

@Sean: Oui, juste un peu de décharge cérébrale. Certainement pourrait utiliser un refactoring. –

+0

Merci Nathan c'est très utile. Y a-t-il un moyen d'obtenir les noms des paramètres avec les types? –

Questions connexes