天天看点

【Java核心技术——反射

  • Class类
Class类:运行时的类型标识的类。
获取Class对象:
  • Object类中的getClass()方法会返回一个Class类型的对象:Class cls = new Date().getClass();
  • 调用静态方法forName获得类名对应的Class对象:Class cls = Class.forName("java.util.Date");
  • T是任意的Java类型,T.class代表T的class对象:Class cls = Date.class;

Java虚拟机为每个类型管理一个Class对象,所以可以用==进行比较操作。

创建一个类的实例:Date date = Date.class.newInstance(); 其中newInstance方法调用默认的无参数构造器。

  • 利用反射分析类的能力:
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;

public class Main {
    
    public static void main(String[] args) {
        
        @SuppressWarnings("resource")
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            
            String name = in.next();
            
            try {
                Class<?> cls = Class.forName(name);
                
                // getModifiers方法一个整型数值,用不同的位开关描述是否使用了public这样的修饰符。
                // Modifier.toString方法将整型数值转换为public这样的修饰符。
                String modifiers = Modifier.toString(cls.getModifiers());
                if (modifiers.length() > 0) {
                    System.out.print(modifiers + " ");
                }
                
                // getName方法返回类的名字。
                System.out.print("class " + cls.getName());
                
                // 个体Superclss方法返回当前类的超类。
                Class<?> supercls = cls.getSuperclass();
                if (supercls != null && supercls != Object.class) {
                    System.out.println(" extends " + supercls.getName());
                }
                
                System.out.println(" {");
                
                printMethods(cls);
                
                System.out.println("}");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    
    public static void printMethods(Class<?> cls) {
        // getMethods方法返回该Class中所有的共有方法Method对象的数组。
        Method[] methods = cls.getMethods();
        
        for (Method method : methods) {
            System.out.print("    ");
            
            String modifiers = Modifier.toString(cls.getModifiers());
            if (modifiers != null) {
                System.out.print(modifiers + " ");
            }
            
            // getReturnType方法返回该Method的返回值Class。
            System.out.print(method.getReturnType().getName());
            
            System.out.print(" ");
            
            System.out.print(method.getName());
            
            System.out.print("(");
            
            // getParameterTypes返回该Method的所有参数类型的Class数组。
            Class<?>[] paramTypes = method.getParameterTypes();
            boolean flag = false;
            for (Class<?> paramType : paramTypes) {
                if (flag) {
                    System.out.print(", ");
                } else {
                    flag = true;
                }
                System.out.print(paramType.getName());
            }
            
            System.out.println(");");
        }
    }
}
           
  • 在运行时使用反射分析对象:
setAccessible(boolean flag):为反射对象设置可访问标志。flag为true表明屏蔽Java的语法检查,使对象的私有属性也可以被查询和设置。
  • 方法指针
在Method类中有一个invoke方法,它允许调用包装在当前Method对象中的方法: Object invoke(Object obj, Object ...args),obj是隐式参数,args是显式参数。