2011-05-17 7 views

答えて

2

興味深い問題です。おそらくあなたが望むものではありませんが、同様のことを行うためのツールは多分あります。確かに、ASMの実装は簡単です。それでは、私はリフレクションを使用して1つを作成しました。

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); 
      } 
     } 
    } 
} 

JAR(およびその依存関係)をクラスパスに含めます。あなたはリフレクションでそれらを得ることができないので、これはパラメータの名前を表示しません。型パラメータやvar-argsも表示されませんが、それらを得ることはできます。

+0

非常に良い解決策、機能はいくつかの異なる方法に分割された場合、私はそれを好むだろうが。しかし、あなたは私がそれを自分でやったようにすべてをやっている。(+1) –

+0

@Sean:うん、ちょっとした脳のダンプ。間違いなく、いくつかのリファクタリングを使用することができます。 –

+0

ありがとうナタンは非常に役立ちます。型と一緒にパラメータ名を取得する方法はありますか? –