RTTI:获取类的详细信息

来源:互联网 发布:matlab 复制矩阵 编辑:程序博客网 时间:2024/05/08 15:53

通过RTTI,Class类和Reflection可以获取某个类的详细信息,包括其没有Public出来的信息,先看一个实例:

[java] view plaincopyprint?
  1. public class ClassExtractor {  
  2.     /** to discard qualifiers */  
  3.     private static final Pattern pattern = Pattern.compile("\\w+\\.");  
  4.       
  5.     private static String removeQualifiers(String name) {  
  6.         return pattern.matcher(name).replaceAll("");  
  7.     }  
  8.       
  9.     public void inheritedMethod() {  
  10.           
  11.     }  
  12.     /** 
  13.      * @param className -- must be full qualified, i.e. with package name, like: java.lang.String, otherwise you get 
  14.      * {@link ClassNotFoundException} 
  15.      * @throws ClassNotFoundException  
  16.      */  
  17.     public static void dumpClassInfo(String className) throws ClassNotFoundException {  
  18.         final StringBuilder sb = new StringBuilder();  
  19.         final Class<?> clazz = Class.forName(className);  
  20.         sb.append(clazz.toString() + " {\n");  
  21.         // Fields  
  22.         // 'Declared' in the Class methods means all the stuff(fields, methods) declared by this class  
  23.         // Class#getDeclaredMethods(), returns all methods declared by this class, including private, public, protected and  
  24.         // package, but excluding inherited methods  
  25.         // while, Class#getMethods(), returns all the public methods, including inherited ones  
  26.         Field[] declaredFields = clazz.getDeclaredFields();  
  27.         if (declaredFields != null) {  
  28.             sb.append("declared fields:\n");  
  29.             for (Field f : declaredFields) {  
  30.                 sb.append("\t" + removeQualifiers(f.toString()) + "\n");  
  31.             }  
  32.         }  
  33.         Field[] fields = clazz.getFields();  
  34.         if (fields != null) {  
  35.             sb.append("feids:\n");  
  36.             for (Field f : fields) {  
  37.                 sb.append("\t" + removeQualifiers(f.toString()) + "\n");  
  38.             }  
  39.         }  
  40.         // Methods  
  41.         Method[] declaredMethods = clazz.getDeclaredMethods();  
  42.         if (declaredMethods != null) {  
  43.             sb.append("declared methods:\n");  
  44.             for (Method m : declaredMethods) {  
  45.                 sb.append("\t" + removeQualifiers(m.toString()) + "\n");  
  46.             }  
  47.         }  
  48.         Method[] methods = clazz.getMethods();  
  49.         if (methods != null) {  
  50.             sb.append("methods:\n");  
  51.             for (Method m : methods) {  
  52.                 sb.append("\t" + removeQualifiers(m.toString()) + "\n");  
  53.             }  
  54.         }  
  55.         // Constructors  
  56.         Constructor<?>[] declaredConstructor = clazz.getDeclaredConstructors();  
  57.         if (declaredConstructor != null) {  
  58.             sb.append("declared constructors:\n");  
  59.             for (Constructor<?> c : declaredConstructor) {  
  60.                 sb.append("\t" + removeQualifiers(c.toString()) + "\n");  
  61.             }  
  62.         }  
  63.         Constructor<?>[] cons = clazz.getConstructors();  
  64.         if (cons != null) {  
  65.             sb.append("constructors:\n");  
  66.             for (Constructor<?> c : cons) {  
  67.                 sb.append("\t" + removeQualifiers(c.toString()) + "\n");  
  68.             }  
  69.         }  
  70.         // Enums  
  71.         Object[] enums = clazz.getEnumConstants();  
  72.         if (enums != null) {  
  73.             sb.append("enums:\n");  
  74.             for (Object o : enums) {  
  75.                 sb.append("\t" + removeQualifiers(o.toString()) + "\n");  
  76.             }  
  77.         }  
  78.         // Inner classes  
  79.         Class<?>[] declaredInnerClasses = clazz.getDeclaredClasses();  
  80.         if (declaredInnerClasses != null) {  
  81.             sb.append("declared inner classes:\n");  
  82.             for (Class<?> c : declaredInnerClasses) {  
  83.                 sb.append("\t" + removeQualifiers(c.toString()) + "\n");  
  84.             }  
  85.         }  
  86.         Class<?>[] innerClasses = clazz.getDeclaredClasses();  
  87.         if (innerClasses != null) {  
  88.             sb.append("inner classes:\n");  
  89.             for (Class<?> c : innerClasses) {  
  90.                 sb.append("\t" + removeQualifiers(c.toString()) + "\n");  
  91.             }  
  92.         }  
  93.         // Super/Base classes  
  94.         Class<?> supers = clazz.getSuperclass();  
  95.         if (supers != null) {  
  96.             sb.append("super classes:\n");  
  97.             sb.append("\t" + removeQualifiers(supers.toString()) + "\n");  
  98.         }  
  99.         // Interfaces  
  100.         Class<?>[] interfaces = clazz.getInterfaces();  
  101.         if (interfaces != null) {  
  102.             sb.append("interfaces:\n");  
  103.             for (Class<?> i : interfaces) {  
  104.                 sb.append("\t" + removeQualifiers(i.toString()) + "\n");  
  105.             }  
  106.         }  
  107.         sb.append("}");  
  108.         System.out.println(sb.toString());  
  109.     }  
  110.     /** 
  111.      * @param args 
  112.      */  
  113.     public static void main(String[] args) {  
  114.         try {  
  115.             dumpClassInfo("java.lang.String");  
  116.             dumpClassInfo("com.effectivejava.rtti.ClassExtractor");  
  117.             dumpClassInfo("com.effectivejava.rtti.ClassExtractorTest");  
  118.         } catch (ClassNotFoundException e) {  
  119.             e.printStackTrace();  
  120.         }  
  121.     }  
  122. }  
这里有另外一个供测试的类:

[java] view plaincopyprint?
  1. public class ClassExtractorTest extends ClassExtractor implements Runnable,  
  2.         Serializable, Cloneable {  
  3.     /** 
  4.      *  
  5.      */  
  6.     private static final long serialVersionUID = -5054007892592227440L;  
  7.   
  8.     private String name;  
  9.     private static long uid;  
  10.       
  11.     public ClassExtractorTest() {  
  12.         // TODO Auto-generated constructor stub  
  13.     }  
  14.   
  15.     public void run() {  
  16.         // TODO Auto-generated method stub  
  17.   
  18.     }  
  19.   
  20.     /** 
  21.      * @param args 
  22.      */  
  23.     public static void main(String[] args) {  
  24.         // TODO Auto-generated method stub  
  25.   
  26.     }  
  27.       
  28.     public void goToSomewhere() {  
  29.           
  30.     }  
  31.       
  32.     public static void die() {  
  33.           
  34.     }  
  35.       
  36.     private void cannotSeeThis() {  
  37.           
  38.     }  
  39.     enum Direction {  
  40.         North,  
  41.         West,  
  42.     };  
  43.     private class InnerClass {  
  44.           
  45.     }  
  46.       
  47.     private static class StaticInnerClass {  
  48.           
  49.     }  
  50. }  
运行结果:

[plain] view plaincopyprint?
  1. class com.effectivejava.rtti.ClassExtractorTest {  
  2. declared fields:  
  3.     private static final long serialVersionUID  
  4.     private String name  
  5.     private static long uid  
  6. feids:  
  7. declared methods:  
  8.     public static void main(String[])  
  9.     public void run()  
  10.     public void goToSomewhere()  
  11.     public static void die()  
  12.     private void cannotSeeThis()  
  13. methods:  
  14.     public static void main(String[])  
  15.     public void run()  
  16.     public void goToSomewhere()  
  17.     public static void die()  
  18.     public void inheritedMethod()  
  19.     public static void dumpClassInfo(String) throws ClassNotFoundException  
  20.     public final native void wait(long) throws InterruptedException  
  21.     public final void wait(long,int) throws InterruptedException  
  22.     public final void wait() throws InterruptedException  
  23.     public boolean equals(Object)  
  24.     public String toString()  
  25.     public native int hashCode()  
  26.     public final native Class getClass()  
  27.     public final native void notify()  
  28.     public final native void notifyAll()  
  29. declared constructors:  
  30.     public ClassExtractorTest()  
  31. constructors:  
  32.     public ClassExtractorTest()  
  33. declared inner classes:  
  34.     class ClassExtractorTest$Direction  
  35.     class ClassExtractorTest$InnerClass  
  36.     class ClassExtractorTest$StaticInnerClass  
  37. inner classes:  
  38.     class ClassExtractorTest$Direction  
  39.     class ClassExtractorTest$InnerClass  
  40.     class ClassExtractorTest$StaticInnerClass  
  41. super classes:  
  42.     class ClassExtractor  
  43. interfaces:  
  44.     interface Runnable  
  45.     interface Serializable  
  46.     interface Cloneable  
  47. }  
其实,没有任何技术含量,主要就是用到java.lang.Class里面的一些接口,但这里面最难理解的就是带有Delcared的方法和其他方法的区别,比如getDeclaredMethods()与getMethods()的区别,通过查文档和实际测试可以发现:

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