栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Panda白话 - 再认识JAVA反射

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Panda白话 - 再认识JAVA反射

最近学习路线:AOP原理 -> JDK 动态代理 -> java 反射
真是人生无常,大肠包小肠呀~~

反射

定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

这个定义看了n遍,每次都是???(小朋友你是否有很多问号?)
最近又看了书、文章、视频,有了新的理解,码下来。。万一对你有用

知识储备(面试高频):

  • 类加载机制
  • jvm内存模型


举个简单说下:

Panda p = new Panda();
Konfu k = new Kongfu();
  1. JVM去磁盘拉取class文件,加载到内存方法区,
  2. 为该类生成一个对应的Class对象,通过该Class对象就能访问JVM中类
  3. 调用类的构造方法创建对象,放入堆内存

Class类

学习反射一定会看到,创建class对象的三种方式:

  1. Class.forName("类的权限定");
  2. 类名.class Panda.class
  3. 对象.getClass()p.getClass()

那么这个Class类到底是个什么类呢,
官方解释: 类的类

  • 上图已经体现出来了,JVM加载类到内存,会为该类生成一个class对象,唯一的
  • 这写class对象抽象出来的类型就是Class类

就是你new一堆panda对象p1、p2、 p3,这些对象的类是Panda
jvm加载类的时候给每个类创建了一个class对象,这些对象的类都是Class

  • 所以上面三个方法获取的都是类文件在内存中对应的唯一的class实例,接收类型都是Class
  • 这个实例中包含类的全部信息,Method、Constructor、Field等
  • Class类提供了丰富的API获取类的内部信息

定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

再看这句话我觉就很好理解了,

  • 任何一个类,都可以通过类名.class 和 Class.forName("类的权限定名") 获取到JVM创建的该类唯一的Class实例,从而获取类的内部结构和信息

  • 任何一个对象,都可以通过对象名.getClass()获取到JVM创建的该类唯一的Class实例,从而获取类的内部结构和信息

  • 平时都是根据类new个对象,在堆里面搞事情,操作的都是副本

  • 现在是反过来了,通过类或对象直接拿到方法区里类的孤本结构和信息

感觉也不太好解释

Class类 API
//获取全部public修饰的构造器
Constructor[] getConstructors()

//获取全部public修饰的方法
Method[] getMethods()

//获取全部public修饰的成员变量
Field[] getFields()
  • 搞一个类
    • 一个私有属性name
    • 一个公有属性age
    • 一个私有无参构造
    • 一个公有有参构造
    • 一个无参info方法
    • 一个有参info方法
public class Panda {
	private String name;
    public int age;
    private Panda() {}
    public Panda(String name) {
        System.out.println("有参构造器。。" + name);
    }
    public void info() {
        System.out.println("无参info方法。。");
    }
    public void info(String name) {
        System.out.println("有参info方法。。" + name);
    }
    class Inner {}
}
  • 验证API
    • getDeclaredConstructors();获取所有构造函数
    • getConstructors(); 获取所有public的构造器
    • getMethods();获取所有public的方法
    • getDeclaredMethod("name"); 获取指定方法
    • getFields(); 获取所有public修饰的属性
    • getDeclaredFields();获取所有属性
    • getDeclaredField("name");获取指定属性名属性
    • getDeclaredClasses(); 获取全部内部类
public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException {
		//通过类名.class反射获取Panda类对应的class实例
        Class apiClass = Panda.class;
        //获取所有构造函数
        Constructor[] declaredConstructors = apiClass.getDeclaredConstructors();
        System.out.println("declaredConstructors:");
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
        //public修饰构造函数
        Constructor[] constructors = apiClass.getConstructors();
        System.out.println("constructors:");
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        //所有public方法
        Method[] methods = apiClass.getMethods();
        System.out.println("methods:");
        for (Method method : methods) {
            System.out.println(method);
        }
        //获取指定名称方法 - 无参
        System.out.println("declaredMethod:"+apiClass.getDeclaredMethod("info"));
        //获取指定名称方法 - 指定参数类型
        System.out.println("declaredMethod:"+apiClass.getDeclaredMethod("info",String.class));
        //获取所有public修饰的属性
        System.out.println("fields:");
        Field[] fields = apiClass.getFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }
        //获取所有属性
        System.out.println("declaredFields:");
        Field[] declaredFields = apiClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName());
        }
        //获取指定属性名属性
        System.out.println("declaredField:"+apiClass.getDeclaredField("name"));
        //获取内部类
        Class[] declaredClasses = apiClass.getDeclaredClasses();
        System.out.println("declaredClass:");
        for (Class declaredClass : declaredClasses) {
            System.out.println(declaredClass);
        }
        Class pandaClassApi$Inner = Class.forName("PandaClassApi$Inner");
        System.out.println("declaringClass:"+pandaClassApi$Inner);
        System.out.println(pandaClassApi$Inner.getPackage());
        System.out.println(pandaClassApi$Inner.getSuperclass());
	}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/918813.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号