文档章节

【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中的反射|SquirrelNote

前言 本篇简介: 反射概述 反射具体功能实现 Android中的反射应用 一、反射(Reflection)概述 1.定义 是指在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法;并且对于任何一个...

跳动的松鼠
2017/11/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

ConcurrentHashMap源码解析

初始化 先看看ConcurrentHashMap中几个重要的属性: // 初始化容量大小static final int DEFAULT_INITIAL_CAPACITY = 16;//默认负载因子static final float DEFAULT_LOAD_FACTOR = 0.75f...

grace_233
11分钟前
0
0
java对象的浅拷贝和深拷贝

浅拷贝 java的数据类型有基本数据类型(如:int、long等)和引用数据类型。例如:对象1中有属性a(基本数据类型)和属性b(引用数据类型),在进行浅拷贝到对象2时,属性a复制属性的值给对象...

yangyangyyyy
12分钟前
0
0
SQLServer AlwaysOn在阿里云的前世今生

缘起 早在2015年的时候,随着阿里云业务突飞猛进的发展,SQLServer业务也积累了大批忠实客户,其中一些体量较大的客户在类似大促的业务高峰时RDS的单机规格(规格是按照 内存CPUIOPS 一定比例...

阿里云云栖社区
13分钟前
0
0
ubuntu16.04 LNMP搭建 php7.1

sudo apt-get update sudo apt-get install mysql-server mysql-client sudo apt-add-repository ppa:ondrej/php sudo apt-get update sudo apt-get install php7.1 php7.1-fpm php7.1-cgi p......

一千零一夜个为什么
19分钟前
0
0
阿里云高级技术专家带你全面了解云主机性能评测

钱超,花名西邪,阿里云高级技术专家,超12年老阿里,是云主机性能领域的知名专家。 在目前的云计算测评领域,很多性能测评存在营销的包装,容易引起误导:比如用瞬时性能引导读者得出结论,...

阿里云官方博客
26分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部