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() + " {\n");
        // 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:\n");
            for (Field f : declaredFields) {
                sb.append("\t" + removeQualifiers(f.toString()) + "\n");
            }
        }
        Field[] fields = clazz.getFields();
        if (fields != null) {
            sb.append("feids:\n");
            for (Field f : fields) {
                sb.append("\t" + removeQualifiers(f.toString()) + "\n");
            }
        }
        // Methods
        Method[] declaredMethods = clazz.getDeclaredMethods();
        if (declaredMethods != null) {
            sb.append("declared methods:\n");
            for (Method m : declaredMethods) {
                sb.append("\t" + removeQualifiers(m.toString()) + "\n");
            }
        }
        Method[] methods = clazz.getMethods();
        if (methods != null) {
            sb.append("methods:\n");
            for (Method m : methods) {
                sb.append("\t" + removeQualifiers(m.toString()) + "\n");
            }
        }
        // Constructors
        Constructor<?>[] declaredConstructor = clazz.getDeclaredConstructors();
        if (declaredConstructor != null) {
            sb.append("declared constructors:\n");
            for (Constructor<?> c : declaredConstructor) {
                sb.append("\t" + removeQualifiers(c.toString()) + "\n");
            }
        }
        Constructor<?>[] cons = clazz.getConstructors();
        if (cons != null) {
            sb.append("constructors:\n");
            for (Constructor<?> c : cons) {
                sb.append("\t" + removeQualifiers(c.toString()) + "\n");
            }
        }
        // Enums
        Object[] enums = clazz.getEnumConstants();
        if (enums != null) {
            sb.append("enums:\n");
            for (Object o : enums) {
                sb.append("\t" + removeQualifiers(o.toString()) + "\n");
            }
        }
        // Inner classes
        Class<?>[] declaredInnerClasses = clazz.getDeclaredClasses();
        if (declaredInnerClasses != null) {
            sb.append("declared inner classes:\n");
            for (Class<?> c : declaredInnerClasses) {
                sb.append("\t" + removeQualifiers(c.toString()) + "\n");
            }
        }
        Class<?>[] innerClasses = clazz.getDeclaredClasses();
        if (innerClasses != null) {
            sb.append("inner classes:\n");
            for (Class<?> c : innerClasses) {
                sb.append("\t" + removeQualifiers(c.toString()) + "\n");
            }
        }
        // Super/Base classes
        Class<?> supers = clazz.getSuperclass();
        if (supers != null) {
            sb.append("super classes:\n");
            sb.append("\t" + removeQualifiers(supers.toString()) + "\n");
        }
        // Interfaces
        Class<?>[] interfaces = clazz.getInterfaces();
        if (interfaces != null) {
            sb.append("interfaces:\n");
            for (Class<?> i : interfaces) {
                sb.append("\t" + removeQualifiers(i.toString()) + "\n");
            }
        }
        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();
        }
    }
}

这里有另外一个供测试的类:

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的方法是返回该类所声明的方法或域,也就是你写这个类时所声明的东西,它包括任何类里面声明的私有的,共有的等等。但是不包括类所继承或实现的方法或域
  • 而其他的方法是返回该类所公开出来的所有接口,包括其声明的公开接口,以及继承来的,所实现的接口

 

转  http://blog.csdn.net/hitlion2008/article/details/7540480

posted @ 2013-03-15 16:50  编程小爬虫  阅读(234)  评论(0编辑  收藏  举报