import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Scanner; /** * 解析目标类的成员信息 */ public class ParseTargetClassMember { public static void main(String[] args) { System.out.println("请输入类型名称:"); //给定的必须是完整的包层次和类名,如java.lang.String String className = new Scanner(System.in).next(); //返回一个字符串的形式的含有完整包名的类名 System.out.println("当前类型:" + className); /** * 获取Class对象 * @see 加载以字符串形式给出的含完整包名的类名所对应的类 * @see 加载类之后,会自动创建并返回一个Class类型的对象,它所描述的就是指定类的信息 */ Class<?> clazz = null; try { clazz = Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } /** * 解析属性信息 */ Field[] declaredFields = clazz.getDeclaredFields(); //获取clazz所关联的数据类型中声明过的所有属性和成员变量,但不包括父类中的 for (Field field : declaredFields) { System.out.println("-----------------------------------------------------------------------------------------"); System.out.println("属性:" + field.toString()); //输出字符串形式的属性格式,包括访问权限、数据类型、属性名、甚至初值等等 System.out.println("/t数据类型:" + field.getType()); //返回当前属性的数据类型 System.out.println("/t属性名:" + field.getName()); //返回当前属性的名字 // 返回当前属性的访问控制修饰符。修饰符可能有多个,如public、static、final等等 int mod = field.getModifiers(); //实际上返回的是一个用整形数值表示的修饰符的组合。比如1代表public,17代表public加static System.out.println("/t属性修饰符:" + Modifier.toString(mod)); //将整型修饰符转换成字符串的表现形式 } /** * 解析方法信息 * @see 即解析当前类型中所封装的方法的信息 */ Method[] declaredMethods = clazz.getDeclaredMethods(); //返回当前类中声明的所有的方法信息。只限于当前类的层次,不包括父类中的 for(Method method : declaredMethods){ System.out.println("-----------------------------------------------------------------------------------------"); System.out.println("方法:" + method.toString()); //输出方法头。也就是方法的标签,方法的格式 System.out.println("/t方法名:" + method.getName()); //解析方法的名字 System.out.println("/t方法修饰符:" + Modifier.toString(method.getModifiers())); //返回该方法的访问控制修饰符 System.out.println("/t返回值类型:" + method.getReturnType()); //它返回的是Class对象,输出时会自动调用toString()方法 System.out.print("/t方法参数列表:"); Class<?>[] parameterTypes = method.getParameterTypes(); //获取当前方法的参数列表,返回每个参数的类型,其均被封装为Class类型 for (int i=0; i<parameterTypes.length; i++) { Class<?> methodParameterType = parameterTypes[i]; if(0 != i){ System.out.print(", "); //输出每一个参数之前打印一个逗号,作为与前一个参数的类型的分隔 } System.out.print(methodParameterType); //Class对象的toString()方法也被重写过,它会输出当前数据类型的名字 } System.out.println(); //输出第二个方法的信息时,换行显示 } /** * 解析构造方法信息 * @see 这里没有获取它的返回值。实际上Constructor类型中也不支持getReturnType()的功能 * @see 因为构造方法在声明的时候,不允许指定它的返回值 * @see 实际上它是有返回值的,即它所属的类的类型。因为构造方法运行的最后,也能够创建一个新对象,并返回其句柄 */ Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); //返回当前类中声明的所有构造方法 for (Constructor<?> constructor : declaredConstructors) { System.out.println("-----------------------------------------------------------------------------------------"); System.out.println("构造方法:" + constructor.toString()); System.out.println("/t方法名:" + constructor.getName()); System.out.println("/t方法修饰符:" + Modifier.toString(constructor.getModifiers())); System.out.print("/t方法参数列表:"); Class<?>[] parameterTypes = constructor.getParameterTypes(); for (int i=0; i<parameterTypes.length; i++) { Class<?> constructorParameterType = parameterTypes[i]; if(0 != i){ System.out.print(", "); } System.out.print(constructorParameterType); } System.out.println(); } System.out.println("-----------------------------------------------------------------------------------------"); /** * 解析当前类的父类 */ Class<?> superClass = clazz.getSuperclass(); //它返回的也是一个Class类型的结果,对应的是当前类的父类 //实际上Class类是一个泛型类。比较规范的用法是给它一个类型参数,即类似于Class<String>的形式 System.out.println("当前类的父类:" + superClass.toString()); System.out.println("-----------------------------------------------------------------------------------------"); /** * 解析当前类实现的接口 */ Class<?>[] interfaces = clazz.getInterfaces(); //获取当前类所实现的所有接口,返回多个接口类型所封装成的Class数组 System.out.println("当前类所实现接口:"); for (Class<?> clazzInterface : interfaces) { System.out.println(clazzInterface.toString()); } System.out.println("-----------------------------------------------------------------------------------------"); /** * 解析当前类型所在包信息 */ Package clazzPackage = clazz.getPackage(); //获取当前类所在的包的信息。如果没有,则返回空的双引号,即一个长度为零的字符串 System.out.println("当前类所在的包:" + clazzPackage.toString()); } }