博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Java动态性】之反射机制 reflection
阅读量:6578 次
发布时间:2019-06-24

本文共 6688 字,大约阅读时间需要 22 分钟。

hot3.png

一、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
c = (Class
)Class.forName(path); /** * 通过反射API调用构造方法、构造对象 * 1. 默认调用了User的无参构造方法 */ User user = c.newInstance(); System.out.println(user); Constructor
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
map, List
list) { System.out.println("Demo03.test01"); } public Map
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(); } }}

转载于:https://my.oschina.net/u/3545495/blog/1861715

你可能感兴趣的文章
SVN 主机IP变更的应对方式
查看>>
自定义蜘蛛网图 NetView
查看>>
【转载】Python中使用线程的技巧
查看>>
跨浏览器的placeholder
查看>>
spring 定时任务执行两次 解决方案
查看>>
MYSQL日期和时间函数
查看>>
[MySQL 5.6] innodb_flush_method新值O_DIRECT_NO_FSYNC 及bug#68555
查看>>
Swagger - 前后端分离后的契约
查看>>
EBER原来这么玩!看这个我也是醉了!
查看>>
MySQL · 捉虫动态 · left-join多表导致crash
查看>>
你知道现在很火的APP推广神器MobLinK技术是什么吗?
查看>>
CSP防运营商劫持
查看>>
【js基础修炼之路】- 微任务,宏任务和Event-Loop
查看>>
从零开始实现一个RPC框架(三)
查看>>
JavaScript 复习之 Date 对象
查看>>
openstack从入门到放弃
查看>>
小程序scroll-view换行问题
查看>>
[Azure DevOps 系列] 二、使用Azure DevOps构建ASP.NET Core应用
查看>>
HTTP常见错误
查看>>
Android5.1.1数据结构解析之ObjectReference、StackReference
查看>>