RTTI:クラスの詳細を取得する


RTTI,Classクラス,Reflectionにより,Publicから出てこないクラスの詳細情報を含むクラスの詳細情報を取得することができ,まずインスタンスを参照する.
public class ClassExtractor {
    /** to discard qualifiers */
    private static final Pattern pattern = Pattern.compile("\\w+\\.");
    
    private static String removeQualifiers(String name) {
        return pattern.matcher(name).replaceAll("");
    }
    
    public void inheritedMethod() {
        
    }
    /**
     * @param className -- must be full qualified, i.e. with package name, like: java.lang.String, otherwise you get
     * {@link ClassNotFoundException}
     * @throws ClassNotFoundException 
     */
    public static void dumpClassInfo(String className) throws ClassNotFoundException {
        final StringBuilder sb = new StringBuilder();
        final Class<?> clazz = Class.forName(className);
        sb.append(clazz.toString() + " {
"); // Fields // 'Declared' in the Class methods means all the stuff(fields, methods) declared by this class // Class#getDeclaredMethods(), returns all methods declared by this class, including private, public, protected and // package, but excluding inherited methods // while, Class#getMethods(), returns all the public methods, including inherited ones Field[] declaredFields = clazz.getDeclaredFields(); if (declaredFields != null) { sb.append("declared fields:
"); for (Field f : declaredFields) { sb.append("\t" + removeQualifiers(f.toString()) + "
"); } } Field[] fields = clazz.getFields(); if (fields != null) { sb.append("feids:
"); for (Field f : fields) { sb.append("\t" + removeQualifiers(f.toString()) + "
"); } } // Methods Method[] declaredMethods = clazz.getDeclaredMethods(); if (declaredMethods != null) { sb.append("declared methods:
"); for (Method m : declaredMethods) { sb.append("\t" + removeQualifiers(m.toString()) + "
"); } } Method[] methods = clazz.getMethods(); if (methods != null) { sb.append("methods:
"); for (Method m : methods) { sb.append("\t" + removeQualifiers(m.toString()) + "
"); } } // Constructors Constructor<?>[] declaredConstructor = clazz.getDeclaredConstructors(); if (declaredConstructor != null) { sb.append("declared constructors:
"); for (Constructor<?> c : declaredConstructor) { sb.append("\t" + removeQualifiers(c.toString()) + "
"); } } Constructor<?>[] cons = clazz.getConstructors(); if (cons != null) { sb.append("constructors:
"); for (Constructor<?> c : cons) { sb.append("\t" + removeQualifiers(c.toString()) + "
"); } } // Enums Object[] enums = clazz.getEnumConstants(); if (enums != null) { sb.append("enums:
"); for (Object o : enums) { sb.append("\t" + removeQualifiers(o.toString()) + "
"); } } // Inner classes Class<?>[] declaredInnerClasses = clazz.getDeclaredClasses(); if (declaredInnerClasses != null) { sb.append("declared inner classes:
"); for (Class<?> c : declaredInnerClasses) { sb.append("\t" + removeQualifiers(c.toString()) + "
"); } } Class<?>[] innerClasses = clazz.getDeclaredClasses(); if (innerClasses != null) { sb.append("inner classes:
"); for (Class<?> c : innerClasses) { sb.append("\t" + removeQualifiers(c.toString()) + "
"); } } // Super/Base classes Class<?> supers = clazz.getSuperclass(); if (supers != null) { sb.append("super classes:
"); sb.append("\t" + removeQualifiers(supers.toString()) + "
"); } // Interfaces Class<?>[] interfaces = clazz.getInterfaces(); if (interfaces != null) { sb.append("interfaces:
"); for (Class<?> i : interfaces) { sb.append("\t" + removeQualifiers(i.toString()) + "
"); } } sb.append("}"); System.out.println(sb.toString()); } /** * @param args */ public static void main(String[] args) { try { dumpClassInfo("java.lang.String"); dumpClassInfo("com.effectivejava.rtti.ClassExtractor"); dumpClassInfo("com.effectivejava.rtti.ClassExtractorTest"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }

ここにはもう1つのテスト用のクラスがあります.
public class ClassExtractorTest extends ClassExtractor implements Runnable,
        Serializable, Cloneable {
    /**
     * 
     */
    private static final long serialVersionUID = -5054007892592227440L;

    private String name;
    private static long uid;
    
    public ClassExtractorTest() {
        // TODO Auto-generated constructor stub
    }

    public void run() {
        // TODO Auto-generated method stub

    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }
    
    public void goToSomewhere() {
        
    }
    
    public static void die() {
        
    }
    
    private void cannotSeeThis() {
        
    }
    enum Direction {
        North,
        West,
    };
    private class InnerClass {
        
    }
    
    private static class StaticInnerClass {
        
    }
}

実行結果:
class com.effectivejava.rtti.ClassExtractorTest {
declared fields:
	private static final long serialVersionUID
	private String name
	private static long uid
feids:
declared methods:
	public static void main(String[])
	public void run()
	public void goToSomewhere()
	public static void die()
	private void cannotSeeThis()
methods:
	public static void main(String[])
	public void run()
	public void goToSomewhere()
	public static void die()
	public void inheritedMethod()
	public static void dumpClassInfo(String) throws ClassNotFoundException
	public final native void wait(long) throws InterruptedException
	public final void wait(long,int) throws InterruptedException
	public final void wait() throws InterruptedException
	public boolean equals(Object)
	public String toString()
	public native int hashCode()
	public final native Class getClass()
	public final native void notify()
	public final native void notifyAll()
declared constructors:
	public ClassExtractorTest()
constructors:
	public ClassExtractorTest()
declared inner classes:
	class ClassExtractorTest$Direction
	class ClassExtractorTest$InnerClass
	class ClassExtractorTest$StaticInnerClass
inner classes:
	class ClassExtractorTest$Direction
	class ClassExtractorTest$InnerClass
	class ClassExtractorTest$StaticInnerClass
super classes:
	class ClassExtractor
interfaces:
	interface Runnable
	interface Serializable
	interface Cloneable
}

実は、技術の含有量は何もありません.主にjavaを使います.lang.Classのインタフェースの中にはいくつかありますが、この中で最も理解しにくいのはDelcaredの方法と他の方法の違いです.例えば、getDeclaredMethods()とgetMethods()の違いです.ドキュメントを調べたり、実際のテストをしたりすることで、次のことがわかります.
  • Declaredを持つメソッドは、クラスが宣言したメソッドまたはドメイン、すなわち、このクラスを書くときに宣言したものを返すことです.それは、クラス内で宣言されたプライベート、共有などが含まれています.ただし、クラスが継承または実装する方法またはドメイン
  • は含まれない.
  • であるが、他の方法は、クラスによって開示されたすべてのインタフェースを返すことであり、その宣言された開示インタフェース、および継承された実装されたインタフェース
  • を含む.