【Java动态性】之反射机制 reflection

1、Java反射机制简介java

      1. 指的是能够于运行时加载、探知、使用编译期间彻底未知到类;数组

      2. 程序在运行状态中,能够动态加载一个只有名称到类,对于任意一个已加载的类,都可以知道这个类的全部属性和方法;对于任意一个对象,都可以调用它都任意一个方法和属性;对象

      3. 加载完类以后,在堆内存中,就产生一个Class类型都对象(一个类只有一个Class对象),这个对象就包含了完整都类都结构信息。能够经过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,因此形象的称之为:反射。内存

      4. Class类介绍:java.lang.Class类十分特殊,用来表示java中类型【class | interface | enum | annotation | primitive type | void 】自己;Class类的对象包含了某个被加载类的结构;一个被加载的类对应一个Class对象;当一个class被加载,或当加载器(class loader)的defineClasss()被JVM调用,JVM便自动产生一个Class对象;Class类是Reflection的根源;针对任何你想动态加载、运行的类、惟有先得到相应的Class对象。get

      5. Class类对象获取方式:1)对象.getClass(); 2)Class.forName("路径");3)类名.class。hash

      6. 反射机制经常使用做用:1)动态加载类、动态获取类的信息(属性、方法、构造器);2)动态构造对象;3)动态调用类和对象的任意方法、构造器;4)动态调用和处理属性;5)获取泛型信息;6)处理注解。it

2、io

public class Demo01 {

    public static void main(String[] args) {
        String path = "com.mimidai.test.User";
        try {
            Class clazz = Class.forName(path);
            System.out.println("clazz.hashCode()= " + clazz.hashCode());
            Class clazz2 = Class.forName(path);
            System.out.println("clazz2.hashCode()=" + clazz2.hashCode());
            /**
             * 一个类只有一个Class对象
             */
            System.out.println(clazz.hashCode() == clazz2.hashCode());
            /**
             * Class对象获取方式
             */
            Class strClazz = String.class;
            Class strClazz2 = path.getClass();
            System.out.println(strClazz == strClazz2);
            /**
             *  Class对象获取跟数组维度有关
             */
            Class intClazz = int.class;
            int[] arr01 = new int[10];
            int[][] arr02 = new int[30][3];
            int[] arr03 = new int[30];
            double[] arr04 = new double[10];
            System.out.println("intClazz.hashCode()=" + intClazz.hashCode());
            System.out.println("arr01.getClass().hashCode()=" + arr01.getClass().hashCode());
            System.out.println("arr02.getClass().hashCode()=" + arr02.getClass().hashCode());
            System.out.println("arr03.getClass().hashCode()=" + arr03.getClass().hashCode());
            System.out.println("arr04.getClass().hashCode()=" + arr04.getClass().hashCode());
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}
public class Demo02 {
    public static void main(String[] args) {
        String path = "com.mimidai.test.User";
        try {
            Class clazz = Class.forName(path);
            /**
             * 获取类的名字
             */
            System.out.println("clazz.getSimpleName(): " + clazz.getSimpleName());
            System.out.println("clazz.getName(): " + clazz.getName());
            /**
             * 获取属性信息
             */
            Field[] fields = clazz.getFields();
            System.out.println("fields.length= " + fields.length);
            for (Field f : fields) {
                System.out.println("属性:" + f);
            }
            Field[] fields2 = clazz.getDeclaredFields();
            System.out.println("fields2.length" + fields2.length);
            for (Field f : fields2) {
                System.out.println("属性:" + f);
            }
            /**
             * 获取方法信息
             */
            Method[] methods = clazz.getDeclaredMethods();
            for (Method m : methods) {
                System.out.println("方法:" + m);
            }
            Method m01 = clazz.getDeclaredMethod("getName", null);
            Method m02 = clazz.getDeclaredMethod("setName", String.class);
            System.out.println("m01: " + m01);
            System.out.println("m02: " + m02);
            /**
             * 获取构造器信息
             */
            Constructor[] constructors = clazz.getDeclaredConstructors();
            for (Constructor constructor : constructors) {
                System.out.println("构造器:" + constructor);
            }
            Constructor constructor = clazz.getDeclaredConstructor(Long.class, String.class, Integer.class);
            System.out.println("constructor: " + constructor);

            Class<User> c = (Class<User>)Class.forName(path);
            /**
             * 经过反射API调用构造方法、构造对象
             * 1. 默认调用了User的无参构造方法
             */
            User user = c.newInstance();
            System.out.println(user);
            Constructor<User> constructor1 = c.getDeclaredConstructor(Long.class, String.class, Integer.class);
            User user2 = constructor1.newInstance(100L, "张三", 19);
            System.out.println("user2.getName(): " + user2.getName());
            /**
             * 经过反射API调用普通方法
             */
            User user3 = c.newInstance();
            Method method = c.getDeclaredMethod("setName", String.class);
            method.invoke(user3, "哈哈");
            System.out.println("user3.getName(): " + user3.getName());
            /**
             * 经过反射API操做属性
             */
            User user4 = c.newInstance();
            Field field = c.getDeclaredField("name");
            field.setAccessible(true);
            field.set(user4, "呵呵");
            System.out.println("user4.getName(): " + user4.getName());
            System.out.println("field.get(user4): " + field.get(user4));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
/**
 * 经过反射获取泛型信息
 */
public class Demo03 {

    public void test01(Map<String, User> map, List<User> list) {
        System.out.println("Demo03.test01");
    }
    public Map<Integer, User> test02() {
        System.out.println("Demo03.test02");
        return null;
    }
    public static void main(String[] args) {
        try {
            /**
             * 获取指定方法参数泛型信息
             */
            Method method = Demo03.class.getMethod("test01", Map.class, List.class);
            Type[] types = method.getGenericParameterTypes();
            for (Type type : types) {
                System.out.println("##" + type);
                if (type instanceof ParameterizedType) {
                    Type[] genericTypes = ((ParameterizedType)type).getActualTypeArguments();
                    for (Type genericType : genericTypes) {
                        System.out.println("泛型类型:" + genericType);
                    }
                }
            }

            /**
             * 获取指定方法返回值泛型信息
             */
            Method method1 = Demo03.class.getMethod("test02", null);
            Type returnType = method1.getGenericReturnType();
            if (returnType instanceof ParameterizedType) {
                Type[] genericTypes = ((ParameterizedType)returnType).getActualTypeArguments();
                for (Type genericType : genericTypes) {
                    System.out.println("返回值,泛型类型:" + genericType);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
相关文章
相关标签/搜索