反射是框架设计的灵魂!但是本文并不是什么高深莫测的框架设计,只是对 Java 反射机制的一次简单总结。温故而知新,可以为师矣!
引
为什么说反射是框架设计的灵魂?其实在学校 Java SE 的时候,并没有去了解反射机制,第一次听说这个名词是在学习 Spring 的时候,其中有两个重要的概念 IOC (动态加载 Bean)和 AOP (动态代理)就是依靠 Java 的反射机制去实现的。除此之外,还有 JDBC 连接数据库时使用 Class.forName()
通过反射加载数据库驱动程序,JDBC 中还使用反射将表字段映射到 Java 对象的 getter/setter
方法的。Jackson、GSON等等类库也是利用反射将 JSON 文件的属性映射到 Java 对象的 getter/setter
方法。
可见反射真的是无处不在!而且是框架设计的灵魂所在!
正文
Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能成为 Java 语言的反射机制。——出自:Java基础之—反射(非常重要)
如何获取 Class 对象?
想要利用反射机制动态的获取类的属性和方法,需要依靠 Class 对象。Class 类对象将一个类的方法、变量等信息都告诉运行的程序。Java 提供了两种方式获取 Class 对象:
-
已经有类的情况下:
Class m1ngClass = M1ng.class;
-
通过
Class.forName()
拿到 Class 对象:(常用)Class m1ngClass = Class.forName("edu.m1ng.test.M1ng");
简单感受一下反射机制
待操作的自定义类:
public class M1ng {
private String name;
private String like;
public M1ng() {
this.name = "m1ng";
this.like = "coding";
}
public void whoami(){
System.out.println("i am "+name);
}
private String like(String name){
return name + " like " + like;
}
}
感受一下反射机制的威力:
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//拿到 Class 对象并创建实例
Class<?> m1ngClass = Class.forName("edu.test.M1ng");
M1ng m1ng = (M1ng) m1ngClass.newInstance();
//获取类中的所有方法(继承自 Object 的方法和自定义的方法)
Method[] allMethods = m1ngClass.getMethods();
for (Method method : allMethods) {
System.out.println(method.getName());
}
//获取指定方法,并调用
Method whoami = m1ngClass.getDeclaredMethod("whoami", null);
Method likeMethod = m1ngClass.getDeclaredMethod("like", String.class);
whoami.invoke(m1ng);
//获取指定参数并修改
Field likeField = m1ngClass.getDeclaredField("like");
likeField.setAccessible(true);
likeField.set(m1ng,"zqc");
//调用私有方法,需要取消安全检查 设置为可访问的
likeMethod.setAccessible(true);
System.out.println(likeMethod.invoke(m1ng,"M1ng"));
}
输出:
whoami
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
i am m1ng
M1ng like zqc
反射机制的优缺点
- 优点:运行期类型的判断,动态加载类,提高代码灵活度。
- 缺点:反射需要一系列的解释处理,通知 JVM 要做的事情,性能肯定要比直接使用明确的 Java 代码要慢得多。而且动态操作去改变类的属性也会增加类的安全隐患。
本人菜鸟,有错误请告知,感激不尽!
更多题解和源码:github
转载:https://blog.csdn.net/qq_42758551/article/details/106265305