java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射
1. 写一个反射的例子
获取类
package leetcode.java.algorithm;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectSample {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class rc = Class.forName("leetcode.java.algorithm.Employee");
Employee o = (Employee) rc.newInstance();
System.out.println(rc.getName());
Method m = rc.getDeclaredMethod("say", String.class);
m.setAccessible(true);
Object invoke = m.invoke(o, "enjoy");
System.out.println(invoke);
Field ename = rc.getDeclaredField("ename");
ename.setAccessible(true);
ename.set(o,"Alice");
Object evoke1 = m.invoke(o, "ahahah");
System.out.println(evoke1);
}
}
2. 类从编译到执行的过程
- 编译器会将Employee.java源文件编译为Employee.class字节码文件
- ClassLoader将字节码转换为JVM中的Class对象
- JVM利用Class对象实例化为Employee对象
3. ClassLoader
- ClassLoader在java中有着非常重要的作用,它主要工作在Class装载的加载阶段,其主要作用是从系统外部获得Class二进制数据流。他是java的核心组件,所有的class都是由classLoader进行加载的,ClassLoader负责通过将Class文件里的二进制数据流装载进系统,然后交给Java虚拟机进行连接、初始化操作。
- ClassLoader的种类:
1 BootStrapClassLoader:C++编写,加载核心库java.*
2 ExtClassLoader:java编写,加载扩展库
3 AppClassLoader:java编写,加载程序所在目录
4 用户自定义classloader,关键函数,findClass, defineClass
4. 类的加载方式
- 隐式加载:new
- 显示加载:loadClass, forName等
loadClass和forName的区别:
都能在运行时对于任意一个类,都能知道其的所有属性和方法,对于任意一个对象,都能调用其任意方法和属性。
类得装载工程:加载(ClassLoader加载)-> 连接 (校验,准备,解析)-> 初始化
Class.forName得到的是已经完成初始化的class
ClassLoader.loadClass得到的是还没有连接的class
避免多份同样字节码的加载