java反射—— 对类的分析

    xiaoxiao2022-06-27  61

    转自http://uuhorse.iteye.com/blog/1706466

    反射API使得Java语言更易实现运行时的动态性,获取Java程序在运行时刻的内部结构,如Java列中的构造方法、域和方法等。反射API的主要功能包括:

        ① 确定一个对象的类     ② 取出类的修饰符(modifiers),字段,方法,构造器和超类     ③ 找出某个接口里定义的常量和方法说明     ④ 创建一个类实例,这个实例在运行时刻才有名字(运行时间才生成的对象)     ⑤ 取得和设定对象数据成员的值,如果数据成员名是运行时刻确定的也能做倒。     ⑥ 在运行时刻调用动态对象的方法

        ⑦ 创建数组,数组大小和类型在运行时刻才确定。也能更改数组成员的值。  

    ① 获取对象的类(Class对象)

    Class c = obj.getClass(); ② 获取一个类的超类

    Class sc = c.getSuperclass(); ③ 获取类的名字

    Class c = obj.getClass(); String name = c.getName(); ④ 获取类的修饰符 

    Class c = obj.getClass(); int m = c.getModifiers();

    此处getModifiers()方法返回的是个整型的结果,结果m并不具体表示哪一种修饰符。先看java.lang.reflect.Modifier类,该类对修饰符进行了相应的包装。     类Modifier中定义了一系列的类描述符常量:Modifier.ABSTRACT、Modifier.FINAL、Modifier.PUBLIC等。getModifiers()方法返回的即是类的所有修饰符分别对应的整型值的或运算结果。

    如public abstract class MyClass{},new MyClass().getClass().getModfiers()即得到Modifier.ABSTRACT | Modifier.PUBLIC。     同时Modifier类提供了一些列的方法,用于判断getModifiers()返回的整型数字中包含的类修饰符:Modifier.isPublic(m)、Modifier.isAbstract(m)、Modifier.isFinal(m)等。

    public class Point { private int x; private int y; private String s1 ="ball"; private String s2="hubin"; private String s3="zhangxiaoxiang"; public Point(int x, int y) { super(); this.x = x; this.y = y; } }

     

    // 分析类的修饰符 public static void printModifiers(Object obj) { System.out.print("Modifier: \n"); Class c = obj.getClass(); int m = c.getModifiers(); if (Modifier.isPublic(m)) System.out.print("public \n"); if (Modifier.isAbstract(m)) System.out.print("abstract \n"); if (Modifier.isFinal(m)) System.out.print("final \n"); System.out.println(c.getName()); } public static void main(String[] args) throws Exception { Point pt1 = new Point(3, 5); printModifiers(pt1); } 输出结果:

    Modifier:  public  reflect.Point ⑤ 确定一个类实现的接口     Class[] theInterfaces = c.getInterfaces();     从上面的语句中可以看到,接口在反射的API中也是用Class表示的,接口是一种特殊的抽象类。可以使用Class类的isInterface()方法判断一个Class类型是一个类还是接口。

    // 分析类的接口 public static void printInterfaceNames(Object o) { Class c = o.getClass(); Class[] theInterfaces = c.getInterfaces(); for (int i = 0; i < theInterfaces.length; i++) { String interfaceName = theInterfaces[i].getName(); System.out.println(interfaceName); } } // 判断接口 public static void verifyInterface(Class c) { String name = c.getName(); if (c.isInterface()) { System.out.println(name + " 是接口."); } else { System.out.println(name + " 是类."); } } ⑥ 获取类的字段     一个类的字段(Field)可能来自本类、父类、实现的接口或者接口的接口,可以使用Class对象的getFields()方法获取类中所有的public属性的字段的数组(Field对象数组)。Field对象提供方法取得字段的名字、类型和描述符,甚至可以给字段赋值或者取字段的值。当然,Class类对象提供了getDeclaredFields()方法获取包括public属性在内的所有在类中声明了的域。 

    // 分析类的字段 public static void printFieldNames(Object o) { Class c = o.getClass(); //public的字段 Field[] publicFields = c.getFields(); for (int i = 0; i < publicFields.length; i++) { String fieldName = publicFields[i].getName(); Class typeClass = publicFields[i].getType(); String fieldType = typeClass.getName(); System.out.println("字段名: " + fieldName + ", 类型: " + fieldType); } //所有的字段 Field[] allFields = c.getDeclaredFields(); for (int i = 0; i < allFields.length; i++) { String fieldName = allFields[i].getName(); Class typeClass = allFields[i].getType(); String fieldType = typeClass.getName(); System.out.println("字段名: " + fieldName + ", 类型: " + fieldType); } } ⑦ 获取构造方法     构造方法是在创建类对象时调用的特殊方法,构造方法可以重载,由它们的参数加以区别。调用getConstructors方法可以取得类构造方法的有关信息,这个方法返回一个数组的 Constructor对象。可以用 Constructor对象里的相关方法来确定构造方法的名字、描述符、参数类型和抛出的意外列表。也可以用Constructor.newInstance创建一个新的Constructor对象。 

    //分析类的构造方法 public static void showConstructors(Object o) { Class c = o.getClass(); Constructor[] theConstructors = c.getConstructors(); for (int i = 0; i < theConstructors.length; i++) { System.out.print(theConstructors[i].getName()); System.out.print(" ( "); Class[] parameterTypes = theConstructors[i].getParameterTypes(); for (int k = 0; k < parameterTypes.length; k++) { String parameterString = parameterTypes[k].getName(); System.out.print(parameterString + " "); } System.out.println(")"); } } ⑧ 获取成员方法     如何找出类的public方法呢?当然是调用getMethods方法。由getMethods方法返回一个数组,数组元素类型是Method对象。方法的名字,类型,参数,描述和抛出的意外都可 以由Method对象的方法来取得。用 Method.invoke 方法自己调用这个方法。     Method类的对象可以通过getName取方法名、getReturnType取返回值的类型、用 getParameterTypes取得参数类型(Class对象)的数组,对每个参数用getName取参数的类型名。     同样,对于非public的方法,可以使用getDeclaredMethods()方法获取。  //分析类中的成员方法 public static void showMethods(Object o) { Class c = o.getClass(); Method[] theMethods = c.getMethods(); for (int i = 0; i < theMethods.length; i++) { String methodString = theMethods[i].getName(); System.out.println("Name: " + methodString); String returnString = theMethods[i].getReturnType().getName(); System.out.println(" Return Type: " + returnString); Class[] parameterTypes = theMethods[i].getParameterTypes(); System.out.print(" Parameter Types:"); for (int k = 0; k < parameterTypes.length; k++) { String parameterString = parameterTypes[k].getName(); System.out.print(" " + parameterString); } System.out.println(); } }

    转载请注明原文地址: https://ju.6miu.com/read-1124082.html

    最新回复(0)