文档章节

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

谢余峰
 谢余峰
发布于 07/23 22:52
字数 1042
阅读 12
收藏 0

一、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对象。

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

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

二、

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();
        }
    }
}

© 著作权归作者所有

共有 人打赏支持
谢余峰
粉丝 0
博文 33
码字总数 26648
作品 0
朝阳
程序员
模拟spring IOC 实现

利用java的反射和动态代理实现IOC 在Java中,其反射和动态代理机制极其强大,我们可以通过其反射机制在运行时获取信息。而代理是一种基本的设计模式,它是一种为了提供额外的或不同的操作而插...

candies
2014/03/02
0
0
java反射机制在项目中的运用

定义: Reflection是java开发语言特性之一,它允许运行中的java程序对自身进行检测,自审,并能操作程序内部的属性和方法,Reflection是java被视为动态语言关键之一。允许程序从执行期的Ref...

zhoulc
2014/02/24
0
2
Android 4.4(KK)中利用APP打开关闭数据流量

在Android 4.4中,在app中打开或关闭数据流量 如果有这方面需求可以参考。 思路 利用JAVA的反射机制(Reflection),来调用CONNECTIVITY_SERVICE完成相关操作。 关于JAVA的反射机制,可以参考...

W_X
2014/12/17
0
4
Java反射机制(未完成,还缺最后一个)

1、背景 1)Reflection也就是反射 是Java被视为动态(或准动态)语言的一个关键性质 2)反射机制指的是程序在运行时能够获取任何类的内部所有信息 2、实现功能概述 1)只要给定类的全名,即可...

萧小蚁
2015/05/03
0
0
最最最常见的Java面试题总结——第二周

String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的? String和StringBuffer、StringBuilder的区别 可变性   String类中使用字符数组:保存字符串,所以String对象是...

Amsour丶
08/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

初级开发-编程题

` public static void main(String[] args) { System.out.println(changeStrToUpperCase("user_name_abc")); System.out.println(changeStrToLowerCase(changeStrToUpperCase("user_name_abc......

小池仔
今天
4
0
现场看路演了!

HiBlock
昨天
12
0
Rabbit MQ基本概念介绍

RabbitMQ介绍 • RabbitMQ是一个消息中间件,是一个很好用的消息队列框架。 • ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的s...

寰宇01
昨天
9
0
官方精简版Windows10:微软自己都看不过去了

微软宣布,该公司正在寻求解决方案,以减轻企业客户的Windows 10规模。该公司声称,企业客户下载整个Windows 10文件以更新设备既费钱又费时。 微软宣布,该公司正在寻求解决方案,以减轻企业...

linux-tao
昨天
14
0
TypeScript基础入门之JSX(二)

转发 TypeScript基础入门之JSX(二) 属性类型检查 键入检查属性的第一步是确定元素属性类型。 内在元素和基于价值的元素之间略有不同。 对于内部元素,它是JSX.IntrinsicElements上的属性类型...

durban
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部