反射机制

来源:互联网 发布:北京全国接单淘宝贷款 编辑:程序博客网 时间:2024/05/22 06:42

反射

能够分析“类”(不是对象)能力的程序称为反射(reflective)

  • 运行中分析类的能力
  • 运行中查看对象
  • 实现通用的数组操纵代码
  • 利用Method对象

Class 类

在程序运行期间,Java运行时系统始终为 所以对象维护一个 被称为运行时的类型标识。这个
信息跟踪着每个对象所属的类。虚拟机利用运行时类型信息选择相应的方法执行。

Object类中的getClass()方法将会返回一个Class类型的实例。
如下是源代码,该方法是一个不被允许重写的方法。

    /**     * Returns the runtime class of this {@code Object}. The returned     * {@code Class} object is the object that is locked by {@code     * static synchronized} methods of the represented class.     *     * <p><b>The actual result type is {@code Class<? extends |X|>}     * where {@code |X|} is the erasure of the static type of the     * expression on which {@code getClass} is called.</b> For     * example, no cast is required in this code fragment:</p>     *     * <p>     * {@code Number n = 0;                             }<br>     * {@code Class<? extends Number> c = n.getClass(); }     * </p>     *     * @return The {@code Class} object that represents the runtime     *         class of this object.     * @see    Class Literals, section 15.8.2 of     *         <cite>The Java™ Language Specification</cite>.     */    public final native Class<?> getClass();  

三种获得* 类类型 *实例 的方法

Object object = new Test();System.out.println(object.getClass().getName());  // 将会输出 yang.Test (yang是我的包名字)String className = "java.util.Date";Class c1 = Class.forName(className);    // 获得当前类类型信息Class c1 = Date.class;

一个Class 对象实际上表示的是一个类型,而这个类型未必一定是一种类。例如:int.class
虚拟机为* 每种类型(基本类型到每一个类)* 管理一个Class对象

Class c = int.classc = Enum.class  c = void.classc = boolean.classc = double.classc = float.classc = Float.classc = new Float(3.4F).getClassc = Class.forName("java.awt.Button")public @interface Ann {}c = Ann.class;// 类型:从基本类型、甚至 void 、boolean类型到数组 int[] 到类到接口到枚举enum到注解都是类型,每种类型都有一个Class对象维护信息。//我们不可以访问这个对象(因为是私有的),它是由虚拟机生成的,引用这个对象方式非常多(如上)。// <基类和子类是两种类型>有两个Class对象。
if(e.getClass() == EObject.class)   //判断对象`e`是不是`EObject`类类型的对象

利用反射分析类的能力

java.lang.reflect
Field Method Constructor分别用于描述类的域、方法、构造器

public class ReflectionTest{   public static void main(String[] args)   {      // read class name from command line args or user input      String name;      if (args.length > 0) name = args[0];      else      {         Scanner in = new Scanner(System.in);         System.out.println("Enter class name (e.g. java.util.Date): ");         name = in.next();      }      try      {         // print class name and superclass name (if != Object)         Class cl = Class.forName(name);         Class supercl = cl.getSuperclass();         String modifiers = Modifier.toString(cl.getModifiers());         if (modifiers.length() > 0) System.out.print(modifiers + " ");         System.out.print("class " + name);         if (supercl != null && supercl != Object.class) System.out.print(" extends "               + supercl.getName());    // Java是单进程方式,所以“实现接口”不算继承方法,只算一种多态性质。         System.out.print("\n{\n");         printConstructors(cl);         System.out.println();         printMethods(cl);         System.out.println();         printFields(cl);         System.out.println("}");      }      catch (ClassNotFoundException e)      {         e.printStackTrace();      }      System.exit(0);   }   public static void printConstructors(Class cl)   {      Constructor[] constructors = cl.getDeclaredConstructors();      for (Constructor c : constructors)      {         String name = c.getName();         System.out.print("   ");         String modifiers = Modifier.toString(c.getModifiers());         if (modifiers.length() > 0) System.out.print(modifiers + " ");                  System.out.print(name + "(");         // print parameter types         Class[] paramTypes = c.getParameterTypes();         for (int j = 0; j < paramTypes.length; j++)         {            if (j > 0) System.out.print(", ");            System.out.print(paramTypes[j].getName());         }         System.out.println(");");      }   }   public static void printMethods(Class cl)   {      Method[] methods = cl.getDeclaredMethods();      for (Method m : methods)      {         Class retType = m.getReturnType();         String name = m.getName();         System.out.print("   ");         // print modifiers, return type and method name         String modifiers = Modifier.toString(m.getModifiers());         if (modifiers.length() > 0) System.out.print(modifiers + " ");                  System.out.print(retType.getName() + " " + name + "(");         // print parameter types         Class[] paramTypes = m.getParameterTypes();         for (int j = 0; j < paramTypes.length; j++)         {            if (j > 0) System.out.print(", ");            System.out.print(paramTypes[j].getName());         }         System.out.println(");");      }   }   public static void printFields(Class cl)   {      Field[] fields = cl.getDeclaredFields();      for (Field f : fields)      {         Class type = f.getType();         String name = f.getName();         System.out.print("   ");         String modifiers = Modifier.toString(f.getModifiers());         if (modifiers.length() > 0) System.out.print(modifiers + " ");                  System.out.println(type.getName() + " " + name + ";");      }   }}

复制数组的好方法

    public static Object[] badCopyOf(Object a[], int newLength) {        Object[] newArray = new Object[newLength]; // 一个对象数组无法转换成实际对象数组        // 设有数组 A[] array = new A[10];        // array是一对象(类型为数组,元素类型为A)        // Object[] arrayTemp = (Object[]) array; // 这是可以的        // Object arrayT = (Object) array; // 可以        // 上述也可以转回去,我们始终要关注 new 的实际对象是谁(反射是最好的查看机制)。// 阿猫阿狗(Object)都可以看家,但这个家究竟是谁的?利用反射机制。        System.arraycopy(a, 0, newArray, 0, Math.min(a.length, newLength));        return newArray;  // 转不会原始实际数组对象类型    }     /**     * A good method of Array copy     * @param a     * @param newLength     * @return     */    public static Object goodCopyOf(Object a, int newLength) {        Class<?> c = a.getClass();        if(!c.isArray()) return null;        Class<?> componentType = c.getComponentType(); // Returns the Class representing the component type of an array.        int length = Array.getLength(a);        Object newArray = Array.newInstance(componentType, newLength);        System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength));        return newArray;    }  

实例

public static void main(String[] args) {        Object object = new Object[10];        if(object.getClass().isArray()) {            Object[] objects = (Object[]) object;            for(int i=0; i<objects.length; i++){                objects[i] = "Fuck you!";            }            for (Object objStr : objects) {                if(objStr.getClass() == String.class){                    System.out.println(objStr.toString());                }                // 或者//                System.out.println(objStr);            }        }  public class Test{    public static void main(String[] args) {        Object object = new Object[10];        if(object.getClass() == String[].class) {    // 条件不成立            Object[] objects = (Object[]) object;            for(int i=0; i<objects.length; i++){                objects[i] = "Fuck you!";            }            for (Object objStr : objects) {//                if(objStr.getClass() == String.class){//                    System.out.println(objStr.toString());//                }//                // 或者                System.out.println(objStr);            }        }    }      public static void main(String[] args) {        Object object = new Object[10];        if(object.getClass() == Object[].class) {    // 可以的            Object[] objects = (Object[]) object;            for(int i=0; i<objects.length; i++){                objects[i] = "Fuck you!";            }            for (Object objStr : objects) {//                if(objStr.getClass() == String.class){//                    System.out.println(objStr.toString());//                }//                // 或者                System.out.println(objStr);            }        }    }  

Java独特的方法调用机制(不太好,容易出错)

public class Test{    public static void main(String[] args) {        try {            Method out = Test.class.getMethod("out", String.class);            out.invoke(new Test(), "OK men and girls");        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {            e.printStackTrace();        }    }    public void out(String str){        System.out.println(str);    }}  
0 0
原创粉丝点击