一、Java类加载器
当程序要使用某个类时,如果该类还没有被加载到内存中,JVM会通过加载、连接、初始化三个步骤,实现对这个类的初始化。
- 加载
将class文件读入JVM内存,并创建一个Class对象,任何类被使用时只有一个Class对象。
- 连接
验证是否有正确的内部结构,并和其他类协调一致
准备负责为类静态成员分配内存,并设置默认初始化
解析该类的二进制数据中的符号引用替换为直接引用
- 初始化
初始化相关步骤
二、Java反射
反射是在运行时根据指定的类获取类的信息。
对于任意一个类,都能够知道这个类的属性和方法;对于任意一个对象,都能够调用它的任意方法与属性。
要想了解一个类,必须先要获得字节码文件对象Class对象。
2.1 通过反射获取Class
获取Class对象的三种方式
- 对象.getClass
- 类名.class
- Class.forName
import agent.Person; /** * 对象.getClass * 类名.class * Class.forName */ public class Reflect { public static void main(String[] args) throws ClassNotFoundException { //方式一 对象.class Person person = new Person(); System.out.println("对象.class "+ person.getClass()); //方式二:类名.class System.out.println("类名.class "+Person.class); //方式三:class.forName System.out.println("class.forName "+Class.forName("agent.Person")); } }
2.2 通过反射获取实现接口及父类
import agent.Person; public class Reflect2 { public static void main(String[] args) { //获取运行时类 Class cl = Person.class; //获取类实现的接口 Class[] interfaces = cl.getInterfaces(); for (Class cls : interfaces){ //获取类接口的名称 System.out.println(cls.getName()); } System.out.println("------------------------"); for (Class cls : interfaces){ //获取类接口的名称的简称 System.out.println(cls.getSimpleName()); } //获取父类 Class class1 = cl.getSuperclass(); System.out.println(class1); } }
2.2 通过反射获取构造
获取构造方法
getConstructors
getDeclaredConstructors
创建对象
newInstance()
con.newInstance()