📖高级语言的反射机制的作用(JAVA示例)

发布: 2020-03-27
热度: 51
趋势: 51
权重: 0
🎯

高级语言的反射机制是一种在运行时动态获取和操作程序结构(如类、方法、属性等)的能力,它使程序能够自省和修改自身行为,广泛应用于框架开发、动态加载、序列化等场景。

什么是反射

反射就是可以在程序运行的时候动态装载类,查看类的信息,生成对象,或操作生成对象。

类在运行的时候,可以得到该类的信息,并且可以动态的修改这些信息,自己能看到自己,跟照镜子一样。

反射并非 Java 特有的技术,但 Java 的反射机制是其语言的核心特性之一,具有高度的系统化和完整性。

反射是高级语言的通用特性,不同语言根据设计哲学提供不同实现:Java/C#强调功能完备,Go 追求高效,Python/JavaScript 则偏向动态性。使用时需权衡灵活性与性能,避免滥用。

JAVA 的反射机制

绝大多数经典的 JAVA 框架均采用了 JAVA 的反射机制来实例化、维护 JAVA 对象。

JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意一个方法和属性;

这种动态获取的信息以及动态调用对象的方法的功能称为 JAVA 语言的反射机制。

JAVA 通常是先有类再有对象,类的对象可以调用方法或者属性。

反射其实是通过 Class 对象来调用类里面的方法。

通过反射可以调用私有方法和私有属性。

反射的作用

如果没有采用反射的机制,A 类如果需要使用 B 类的方法,必须要求 B 类已经完成方法的编写(编译),否则 A 类无法通过编译。

而利用 JAVA 的反射机制,A 类可以在未得到 B 类完成编译时能够完成自己身代码的编译。

JAVA 的反射机制提供了这些能力:

  1. 运行时判断任意一个对象所属的类
  2. 运行时构造任意一个类的对象
  3. 运行时判断任意一个类所具有的成员变量和方法
  4. 运行时调用任意一个对象的方法
  5. 生成动态代理

JAVA 的反射机制能够探知类的基本结构,这种能力被称为 JAVA 类的“自审”。

开发常用的 eclipse 和 idea,当我们构建出一个对象的时候,去调用该对象的方法和属性的时候,一按点.编译工具就会将该对象可用的所有的方法和属性全部都列出来,供用户进行选择,就是利用了 JAVA 的反射原理,对创建的对象的探知、自审。

反射技术被大量用于 JAVA 设计模式和框架技术,最常见的设计模式就是工厂模式和单例模式。

反射的实现

反射的实现主要借助四个类:Class、Constructor、Field、Method

通过 Class 类获取类对象

//获取Class类的三种方式
Class<User> userClass;
//.class
userClass = User.class;
//类名全路径
userClass = (Class<User>) Class.forName("com.mebugs.user");
//对象获取Class
User user = new User();
userClass = (Class<User>) user.getClass();
//Class获取对象
User tom = userClass.newInstance();

Class 类获取 Constructor 构造方法

//Class类获取构造方法
Class<User> consClass = User.class;
//全部公共构造方法数组
Constructor<User>[] allPubCons = (Constructor<User>[]) consClass.getConstructors();
//根据入参获取指定公共构造方法
Constructor needPubCons = consClass.getConstructor(new Class[]{int.class,String.class});
//全部构造方法(包含私有)
Constructor<User>[] allCons = (Constructor<User>[]) consClass.getDeclaredConstructors();
//根据入参获取指定构造方法(包含私有)
Constructor needCons = consClass.getDeclaredConstructor(new Class[]{int.class,String.class});

Class 类获取属性

//Class类获取属性
Class<User> fieldClass = User.class;
//获取指定的公共属性(类或接口的指定已声明字段类对象)
Field pubName = fieldClass.getField("name");
//获取全部公共属性(类或接口的指定已声明字段类对象)
Field[] allPubFiels = fieldClass.getFields();
//获取指定的属性(类或接口的指定已声明字段类对象)
Field name = fieldClass.getDeclaredField("name");
//获取全部属性(类或接口的指定已声明字段类对象)
Field[] allFiels = fieldClass.getDeclaredFields();

Class 类获取方法

//Class类获取方法
Class<User> modClass = User.class;
//获取指定的公共方法
Method pubDo = modClass.getMethod("do",new Class[]{int.class,String.class});
//获取全部公共方法
Method[] allPubMo = fieldClass.getMethods();
//获取指定的方法
Method doMo = modClass.getDeclaredMethod("do",new Class[]{int.class,String.class});
//获取全部方法
Method[] allMo = fieldClass.getDeclaredMethods();

备注

ClassForName 与 ClassLoader 的区别:

  • class.forName()除了将类的.class 文件加载到 JVM 中会对类进行解释、执行类中的 static 块以及静态变量赋值的静态方法
  • classLoader 只干一件事情,就是将.class 文件加载到 JVM 中
当前文章暂无讨论,留下脚印吧!
大纲
  • 什么是反射
    • JAVA 的反射机制
  • 反射的作用
  • 反射的实现
    • 通过 Class 类获取类对象
    • Class 类获取 Constructor 构造方法
    • Class 类获取属性
    • Class 类获取方法
  • 备注
提交成功,请等待审核通过后全面展示!

发表评论

昵称
邮箱
链接
签名
评论

温馨提示:系统将通过浏览器临时记忆您曾经填写的个人信息且支持修改,评论提交后仅自己可见,内容需要经过审核后方可全面展示。

选择头像