(1)、类的加载
当程序要执行某个类的时候,如果这个类还没有被加载到内存中,系统会通过加载、链接、初始化三步来实现对这个类的初始化。
加载: 加载就是把class文件读入到内存中,并对应的创建一个Class对象,任何类被使用的时候系统都会建立一个Class对象 链接: 验证 内部结构是否是正确的,并且和其他类协调一致 准备 负责为类的静态成员分配内存空间,并设置默认初始化值 解析 把类的二进制数据中的符号引用替换为直接引用 初始化: 执行静态代码块给静态变量初始化
(2)、类的初始化时机
创建类的实例 访问类的静态变量,或者在给静态变量赋值 调用类的静态方法 使用反射方式来创建某个类或者接口对应的Class对象 初始化某个类的子类 使用java命令运行某个主类
(3)、类加载器
负责把.class文件加载到内存中,并生成对应的Class对象。
类加载器的组成:
根类加载器(引导类加载器、 Bootstrap ClassLoader):负责java核心类的加载。String、System、double……等,在jdk中的jre中的lib中的rt.jar。
扩展类加载器(Extension ClassLoader):负责jre的扩展目录中jar包的加载,在jdk中的jre中的lib中的ext目录下
系统类加载器(System ClassLoader):负责在jvm启动时加载来自java命令的class文件。
(4)反射
就是通过class文件对象,去使用该文件中的成员变量、成员方法和构造方法。先要得到这个class文件对象,其实就是要得到Class(class是Class的实例)类的对象。
获取class文件对象的方式:Object类中的getClass()方法;数据类型的静态属性class;Class类中的静态方法public static Class forName(String className)
开发用第三种,因为不是具体的类名,这样我们就可以把这个字符串写到配置文件中去。
构造方法
public Constructor<?>[] getConstructors()获取所有共有的构造方法
public Constructor<?>[] getDeclaredConstructors()获取所有的构造方法
创建对象
public T newInstance()
获取单个的构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes),获取单个公共的构造方法对象,参数表示的是:你要获取的构造方法的构造参数个数以及参数的数据类型的class字节码文件对象
public Constructor<T> getDeclaredConstructor(类<?>... parameterTypes),获取私有构造方法对象
public void setAccessible(boolean flag),将此对象的accessible标志设置为指示的布尔值。 true的值表示反射对象应该在使用时抑制Java语言访问检查,false的值表示反映的对象应该强制执行Java语言访问检查。
Constructor con = c.getConstructor(),返回的是无参共有构造方法对象
public T newInstance(Object... initargs),使用由此Constructor对象表示的构造函数,使用指定的初始化参数创建和初始化构造函数的声明类的新实例。
Constructor con = c.getConstructor(String.class,int.class,String.class),获取带参构造对象
Object obj = con.newInstance("AA",18,"帅哥"),通过带参构造方法对象创建对象
Constructor con = c.getDeclaredConstructor(),获取私有构造
con.setAccessible(true),取消java语言访问检查,没有则会报异常。
java.lang.IllegalAccessException:非法的存取异常
获取所有成员对象
public Field[] getDeclaredFields(),包括私有
public Field[] getFields(),公有
获取单个成员对象的
public Field getDeclaredField(String name),包括私有
public Field getField(String name),公有
设置成员值
public void set(Object obj,Object value),将指定对象参数上的此Field对象表示的字段设置为指定的新值
Constructor con = c.getConstructor();//通过无参构造方法创建对象并赋值
Object obj = con.newInstance();
System.out.println(obj);
Field nameField = c.getDeclaredField("name");//给指定对象上的Field对象表示的字段属性设置指定的值
nameField.setAccessible(true);
nameField.set(obj, "AAA");//给obj对象的nameField属性赋值。
Student s = (Student)obj;
Sys