Java反射之解析目标类的成员信息


  1. package com.jadyer.reflection;   
  2.   
  3. import java.lang.reflect.Constructor;   
  4. import java.lang.reflect.Field;   
  5. import java.lang.reflect.Method;   
  6. import java.lang.reflect.Modifier;   
  7. import java.util.Scanner;   
  8.   
  9. /**  
  10.  * 解析目标类的成员信息  
  11.  */  
  12. public class ParseTargetClassMember {   
  13.     public static void main(String[] args) {   
  14.         System.out.println("请输入类型名称:"); //给定的必须是完整的包层次和类名,如java.lang.String   
  15.         String className = new Scanner(System.in).next(); //返回一个字符串的形式的含有完整包名的类名   
  16.         System.out.println("当前类型:" + className);   
  17.   
  18.         /**   
  19.          * 获取Class对象  
  20.          * @see 加载以字符串形式给出的含完整包名的类名所对应的类  
  21.          * @see 加载类之后,会自动创建并返回一个Class类型的对象,它所描述的就是指定类的信息  
  22.          */  
  23.         Class<?> clazz = null;   
  24.         try {   
  25.             clazz = Class.forName(className);   
  26.         } catch (ClassNotFoundException e) {   
  27.             e.printStackTrace();   
  28.         }   
  29.            
  30.         /**  
  31.          * 解析属性信息  
  32.          */  
  33.         Field[] declaredFields = clazz.getDeclaredFields(); //获取clazz所关联的数据类型中声明过的所有属性和成员变量,但不包括父类中的   
  34.         for (Field field : declaredFields) {   
  35.             System.out.println("-----------------------------------------------------------------------------------------");   
  36.             System.out.println("属性:" + field.toString()); //输出字符串形式的属性格式,包括访问权限、数据类型、属性名、甚至初值等等   
  37.             System.out.println("\t数据类型:" + field.getType()); //返回当前属性的数据类型   
  38.             System.out.println("\t属性名:" + field.getName()); //返回当前属性的名字   
  39.             // 返回当前属性的访问控制修饰符。修饰符可能有多个,如public、static、final等等   
  40.             int mod = field.getModifiers(); //实际上返回的是一个用整形数值表示的修饰符的组合。比如1代表public,17代表public加static   
  41.             System.out.println("\t属性修饰符:" + Modifier.toString(mod)); //将整型修饰符转换成字符串的表现形式   
  42.         }   
  43.            
  44.         /**   
  45.          * 解析方法信息  
  46.          * @see 即解析当前类型中所封装的方法的信息  
  47.          */  
  48.         Method[] declaredMethods = clazz.getDeclaredMethods(); //返回当前类中声明的所有的方法信息。只限于当前类的层次,不包括父类中的   
  49.         for(Method method : declaredMethods){   
  50.             System.out.println("-----------------------------------------------------------------------------------------");   
  51.             System.out.println("方法:" + method.toString()); //输出方法头。也就是方法的标签,方法的格式   
  52.             System.out.println("\t方法名:" + method.getName()); //解析方法的���字   
  53.             System.out.println("\t方法修饰符:" + Modifier.toString(method.getModifiers())); //返回该方法的访问控制修饰符   
  54.             System.out.println("\t返回值类型:" + method.getReturnType()); //它返回的是Class对象,输出时会自动调用toString()方法   
  55.             System.out.print("\t方法参数列表:");   
  56.             Class<?>[] parameterTypes = method.getParameterTypes(); //获取当前方法的参数列表,返回每个参数的类型,其均被封装为Class类型   
  57.             for (int i=0; i<parameterTypes.length; i++) {   
  58.                 Class<?> methodParameterType = parameterTypes[i];   
  59.                 if(0 != i){   
  60.                     System.out.print(", "); //输出每一个参数之前打印一个逗号,作为与前一个参数的类型的分隔   
  61.                 }   
  62.                 System.out.print(methodParameterType); //Class对象的toString()方法也被重写过,它会输出当前数据类型的名字   
  63.             }   
  64.             System.out.println(); //输出第二个方法的信息时,换行显示   
  65.         }   
  66.            
  67.         /**   
  68.          * 解析构造方法信息  
  69.          * @see 这里没有获取它的返回值。实际上Constructor类型中也不支持getReturnType()的功能  
  70.          * @see 因为构造方法在声明的时候,不允许指定它的返回值  
  71.          * @see 实际上它是有返回值的,即它所属的类的类型。因为构造方法运行的最后,也能够创建一个新对象,并返回其句柄  
  72.          */  
  73.         Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); //返回当前类中声明的所有构造方法   
  74.         for (Constructor<?> constructor : declaredConstructors) {   
  75.             System.out.println("-----------------------------------------------------------------------------------------");   
  76.             System.out.println("构造方法:" + constructor.toString());                  
  77.             System.out.println("\t方法名:" + constructor.getName());   
  78.             System.out.println("\t方法修饰符:" + Modifier.toString(constructor.getModifiers()));   
  79.             System.out.print("\t方法参数列表:");   
  80.             Class<?>[] parameterTypes = constructor.getParameterTypes();   
  81.             for (int i=0; i<parameterTypes.length; i++) {   
  82.                 Class<?> constructorParameterType = parameterTypes[i];   
  83.                 if(0 != i){   
  84.                     System.out.print(", ");   
  85.                 }   
  86.                 System.out.print(constructorParameterType);   
  87.             }   
  88.             System.out.println();   
  89.         }   
  90.         System.out.println("-----------------------------------------------------------------------------------------");   
  91.            
  92.         /**   
  93.          * 解析当前类的父类  
  94.          */  
  95.         Class<?> superClass = clazz.getSuperclass(); //它返回的也是一个Class类型的结果,对应的是当前类的父类   
  96.         //实际上Class类是一个泛型类。比较规范的用法是给它一个类型参数,即类似于Class<String>的形式   
  97.         System.out.println("当前类的父类:" + superClass.toString());         
  98.         System.out.println("-----------------------------------------------------------------------------------------");   
  99.            
  100.         /**   
  101.          * 解析当前类实现的接口  
  102.          */  
  103.         Class<?>[] interfaces = clazz.getInterfaces(); //获取当前类所实现的所有接口,返回多个接口类型所封装成的Class数组   
  104.         System.out.println("当前类所实现接口:");   
  105.         for (Class<?> clazzInterface : interfaces) {   
  106.             System.out.println(clazzInterface.toString());   
  107.         }              
  108.         System.out.println("-----------------------------------------------------------------------------------------");   
  109.            
  110.         /**   
  111.          * 解析当前类型所在包信息  
  112.          */  
  113.         Package clazzPackage = clazz.getPackage(); //获取当前类所在的包的信息。如果没有,则返回空的双引号,即一个长度为零的字符串   
  114.         System.out.println("当前类所在的包:" + clazzPackage.toString());   
  115.     }   
  116. }  

相关内容