• Java反射01——基本概念


    本文的主要资料来源于《Thinking in Java》以及尚硅谷宋宏康老师的视频课程,附上视频链接:https://www.bilibili.com/video/BV1Kb411W75N,有兴趣的读者可以自行B站前往观看

    1.反射的概念

    反射是被视为动态语言的关键,反射机制允许程序在执行期间借助Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性和方法。反射就是在编译的时候将类的结构保存到方法区中,只有在运行时才动态地获取类的对象、属性、方法

    2.为什么要使用反射

    一般的,我们获取某个类的对象最常用的方式是使用new()关键字,来创造一个具体的对象,而这个对象是在编译期间就已经创建好了的。那么为什么需要在运行期也创建对象呢,这里就涉及到另一个Java特性——泛型。

    3.反射的运行原理

    Java虚拟机在读取某个类的文件字节码(.class文件)的时候,会将这个类加载到JVM之中,并产生一个Class对象,而且只会产生一个,这个Class对象包含了该类的属性、方法、构造函数、包等各种信息,在运行时期间,外部可以通过某些手段动态地获取该类的这些信息,具体类的加载流程参见《深入理解Java虚拟机》。

    图1 Java中正常创建对象和反射的流程

    4.反射的使用

    4.1获取Class类的三种方式

    以Apple类为例

    class Apple {
        public String name;
        public Integer type;
        
        public Apple(){}
    
        public Apple(String name, Integer type) {
            this.name = name;
            this.type = type;
        }
    }
    

    在Test类中使Apple类

    public static void main(String[] args) throws ClassNotFoundException {
          /* 1.使用Class.forName方法 */
          Class<?> clazz = Class.forName("com.kundi.loader.Apple");
    
          /* 2.使用类的.class属性 */
          Class<Apple> aClass = Apple.class;
    
          /* 3.使用对象的.getClass方法 */
          Apple apple = new Apple();
          Class<? extends Apple> aClass1 = apple.getClass();
    
      }
    

    上面的<?>属于泛型的范畴,看不懂的可以忽略,重点是Class类。不难看出,上面三种创建Class对象的三种方式中,第一种是相对方便,也是最常用的,因为可以根据参数字符串确定所要创建的Class对象;而第二中则需要提前知道类名,缺少灵活性;第三种就更不灵活了,都已经获取了对象了,再获取Class对象意义不大,除非是要调用某些访问修饰符为private或其他访问不到的类型。

    4.2 Class类的使用

    那么,拿到了Class类能够干什么用呢?是否真如想象中的那么灵活?关于反射类的包,均存在于JDK的java.lang.reflect包下,里面的API也很多,但并不是每一样都能用得上,典型的用的比较多的有下面这些:
    (1)通过反射创建类的对象

    Apple apple1= (Apple)clazz.newInstance();
    

    注意:这里要将Object类强转为Apple类,而且使用Class.newInstance()使用的是默认无参构造方法
    (2)获取反射类的构造器

    Constructor constructor = clazz.getConstructor(String.class, Integer.class);
    Apple apple2 = (Apple) constructor.newInstance("红富士", 1);
    

    这里可以获取有参的构造方法,然后创建对象
    (3)获取反射类的方法

    Method[] methods = clazz.getMethods();
        for (Method method: methods) {
        System.out.println(method.getName());
    }
    

    打印结果如下:

    除了Object本身自带的方法之外,也打印了Apple类的方法
    (4)获取反射类的属性
    其实在JavaSE部分,反射类用的并不多,而在JavaEE方面特别是Spring框架中用的比较广泛。

    参考文章

    [1]Java反射介绍
    [2]大白话说Java反射:入门、使用、原理

  • 相关阅读:
    常用地址
    三步搭建Spring Cloud 服务注册
    Java判断两个时间段是否有交集
    CentOS-7下安装docker
    linux 版菱形
    《少林问道》
    Linux下安装Nginx详细图解教程
    测试
    CentOS修改主机名和主机表
    虚拟机中CentOS配置静态网络
  • 原文地址:https://www.cnblogs.com/dabenhou/p/13915150.html
Copyright © 2020-2023  润新知