反射是框架设计的灵魂,而反射是基于动态实现的
动态:
动态相对于静态而言的。c和c++是静态的,javascript和python是动态的,而java有一定的动态性
动态语言是值 程序在运行是能够改变程序结构和变量类型的语言,使得语言的功能更加强大
动态的为什么更强大呢?举一个例子
// 静态Student student = new Student();
student.study("数学");
// 动态// 1.载入类对象//加载完类以后,就会在堆内存里产生一个class 类型的对象,这个对象就包含了完整的类的结构信息Class class =Class.forName("Student");
// 2.调用默认无参构造器生成对象Object object = class.newInstance();
// 3.强制转型Student student = (Student) object;
ve.study("数学");
现在假如没有Student这个类,第一段代码不能通过编译,但是第二段代码能通过编译,会抛出ClassNotFoundException的异常
这与java 的类加载机制有关了。我们编写的.java文件首先被编译器编译成一个字节码文件(即.class文件),当需要某个类的时候,java虚拟机会加载 .class 文件,并创建对应的class对象,将class文件加载到虚拟机的内存
但从效率来说,静态执行的效率肯定远高于动态
反射:
在java里提供了一个叫做java.lang.reflect的库,简单来说,通过它,可以获取 类名 类的属性,方法 ,构造器并进行操作
可获取包括该class的modifiers(诸如public, static等等)、superclass(例如Object)、实现的interfaces,也包括field(属性)和methods(方法)以及Constructor(构造器),并可以改变属性的值,调用方法和构造器
Java反射机制主要提供了以下功能
在运行时构造任意一个类的对象
在运行时获取任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法(属性)
搞不懂没关系,举个例子
假如有一个Student类
public class Student {
// 属性public String name;
public int age;
// 构造器public Student(String name,int age) {
this.name = name;
this.age = age;
}
// 方法 public string study(String string){
return string;
}
}
// 载入类对象Class class =Class.forName("Student");
Object object = class.newInstance();
Student student = (Student) object;
//获取类的名称并输出String className = c.getName();
System.out.println("className:" + className);
//查询该类对象的方法(这里只有study)java.lang.reflect.Method[] methods = c.getMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println("methods:" + methods[i].getName());
}
// 查询该类的构造器java.lang.reflect.Constructor[] cons = c.getConstructors();
for (int i = 0; i < cons.length; i++) {
System.out.println("cons:" + cons[i].getName());
}
// 查询改类的属性(这里java.lang.reflect.Field[] fields = c.getFields();
for (int i = 0; i < fields.length; i++) {
System.out.println("fields:" + fields[i].getName());
}
// 查询该类的父类Class superClass = c.getSuperclass();
System.out.println("superClass:" + superClass.getName());
// 查询该类实现的接口Class[] interfaces = c.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
System.out.println("interfaces:" + interfaces[i].getName());
}
下面是对方法和属性进行操作
//通过反射API执行方法Method m1 = class.getMethod("study", String.class);
m1.invoke(student, "数学");
//通过反射API操作属性 Field f1 = clazz.getDeclaredField("name");
f1.setAccessible(true); //跳过安全检查,即可以操作非公有属性了。提高效率的常用方式 f1.set(student, 13);
System.out.println(stu1.getAge());
java动态反射的应用是ORM框架(目前知道),它是连接对象和数据库层次的桥梁,实现了关系对象到数据库的映射
作为菜鸡,关于反射的基本内容介绍差不多就这么多了,虽然知识一点皮毛,但说明的入门很轻松。要学得更深还要通过实战。希望各位也能继续加油。