高级语言的反射机制是一种在运行时动态获取和操作程序结构(如类、方法、属性等)的能力,它使程序能够自省和修改自身行为,广泛应用于框架开发、动态加载、序列化等场景。
反射就是可以在程序运行的时候动态装载类,查看类的信息,生成对象,或操作生成对象。
类在运行的时候,可以得到该类的信息,并且可以动态的修改这些信息,自己能看到自己,跟照镜子一样。
反射并非 Java 特有的技术,但 Java 的反射机制是其语言的核心特性之一,具有高度的系统化和完整性。
反射是高级语言的通用特性,不同语言根据设计哲学提供不同实现:Java/C#强调功能完备,Go 追求高效,Python/JavaScript 则偏向动态性。使用时需权衡灵活性与性能,避免滥用。
绝大多数经典的 JAVA 框架均采用了 JAVA 的反射机制来实例化、维护 JAVA 对象。
JAVA 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为 JAVA 语言的反射机制。
JAVA 通常是先有类再有对象,类的对象可以调用方法或者属性。
反射其实是通过 Class 对象来调用类里面的方法。
通过反射可以调用私有方法和私有属性。
如果没有采用反射的机制,A 类如果需要使用 B 类的方法,必须要求 B 类已经完成方法的编写(编译),否则 A 类无法通过编译。
而利用 JAVA 的反射机制,A 类可以在未得到 B 类完成编译时能够完成自己身代码的编译。
JAVA 的反射机制提供了这些能力:
JAVA 的反射机制能够探知类的基本结构,这种能力被称为 JAVA 类的“自审”。
开发常用的 eclipse 和 idea,当我们构建出一个对象的时候,去调用该对象的方法和属性的时候,一按点.编译工具就会将该对象可用的所有的方法和属性全部都列出来,供用户进行选择,就是利用了 JAVA 的反射原理,对创建的对象的探知、自审。
反射技术被大量用于 JAVA 设计模式和框架技术,最常见的设计模式就是工厂模式和单例模式。
反射的实现主要借助四个类:Class、Constructor、Field、Method
//获取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类获取构造方法
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<User> fieldClass = User.class;
//获取指定的公共属性(类或接口的指定已声明字段类对象)
Field pubName = fieldClass.getField("name");
//获取全部公共属性(类或接口的指定已声明字段类对象)
Field[] allPubFiels = fieldClass.getFields();
//获取指定的属性(类或接口的指定已声明字段类对象)
Field name = fieldClass.getDeclaredField("name");
//获取全部属性(类或接口的指定已声明字段类对象)
Field[] allFiels = fieldClass.getDeclaredFields();
//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 的区别:
温馨提示:系统将通过浏览器临时记忆您曾经填写的个人信息且支持修改,评论提交后仅自己可见,内容需要经过审核后方可全面展示。