1,类加载机制:启动JVM,加载字节码。
当调用java命令来运行某个java程序时。该命令将会启动一个JVM进程,同一个JVM中的所有程,变量都处于同一个进程中,共享该JVM的内存区域。
当出现以下情况时,JVM会退出:
1)程序正常执行结束
2)使用System.exit(0)方法
3)出现异常时,没有捕获异常
4)平台强制结束JVM进程
JVM进程一旦结束,该进程中内存中的数据将会丢失
2,类的加载:
类加载是指将类的class文件载入内存中,并为之创建一个java.lang.Class对象,我们称之为字节码对象。
类的加载过程由类的加载器完成,类加载器通常由JVM提供,我们称之为系统类加载器,我们也可以继承ClassLoader类来提供自定义类加载器,不同的类加载器可以实现加载本地字节码文件,jar包中的字节码,通过网络加载字节码。
2,类的连接:
当类被加载进内存之后,系统为之生产一个对应的Class对象,接着把类的二进制数据合并到JRE中
1)验证:检测加载的类是否有正确的内部结构
2)准备:负责为类的static变量分配内存,并设置默认值
3)解析:把类的二进制数据中的符号引用替换为直接引用
3,类的初始化:
在此阶段,JVM负责对类进行初始化,主要对static变量进行初始化
类的初始化包含一下步骤:
1)如果该类还未被加载和连接,则程序先加载并连接该类
2)如果该类的直接父类还未被初始化,则先初始化其父类
3)如果类中的初始语句(静态代码块),则系统依次执行这些初始化语句
什么是反射?
1)对象都有编译类型和运行类型
Object obj = new java.util.Date();
编译类型:Object
运行类型:java.util.Date
需求:通过obj对象调用java.util.Date类中的toLocaleString方法
此时会编译失败,因为编译时检查Object中,没有该方法
三种方式获取对象的字节码:
1)使用类名.class获取
2)使用Object类的getClass()方法
3)使用Class类的forName(String className)方法
注意:同一个类在JVM中只存在一份字节码对象,也就是说clz1==clz2==clz3
java.lang.Class九大内置Class实例:
byte,short,int,long,float,double,char,boolean,void
数组的Class实例:
相同维数的同一数据类型的数组共享同一个Class对象
获取构造器:
1)获取该类的字节码对象
2)从该字节码对象中去找需要获取的构造器
Class类获取构造器方法:
Constructor类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器
public Constructor<?>[] getConstructors():获取当前Class所表示的类的public修饰的构造器
public Constructor<?>[] getDeclaredConstructors():获取当前类的所有构造器,与访问权限无关
public Constructor<?>[] getConstructor(Class<?>...ParameterTypes):获取当前类中指定的一个public的构造器
参数parameterTypes表示构造器参数的Class类型
public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):获取当前Class所表示类中指定的一个构造器
通过获取的构造器创建对象:
1)找到构造器所在类的字节码对象
2)获取构造器
3)使用构造器创建对象
通过设置setAccessible(true);使得私有构造器可以访问。
注意:不单Constructor有newInstance方法
Class类也有newInstance方法,但是只能调用无参构造方法
使用反射获取类中的方法:
1)获取方法所在类的字节码对象
2)获取方法
常用方法:
public Method[] getMethods():获取包括自身和继承过来的所有public方法
public Method[] getDeclareMethods():获取自身所有的方法(不包括继承的,与访问权限无关)
public Method getMethod(String methodName,Class<?>...parameterTypes):表示调用指定的一个公共的方法(包括继承的)
参数:
methodName:表示被调用方法的名字
parameterTypes:表示被调用方法的参数的Class类型
public Method getDeclaredMethod(String name,Class<?>...parameterTypes):表示调用指定一个本类中的方法(不包括继承的)
参数:
methodName:表示被调用方法的名字
parameterTypes:表示被调用方法的参数的Class类型
使用反射调用方法:
如何使用反射调用一个方法:
在Method中有一个方法:
public Object invoke(Object obj,Object...args):表示调用当前Method所表示的方法
参数:
obj:表示被调用的方法底层所属对象
args:表示调用方法时传递的实际参数
返回:
底层方法的返回结果
调用私有方法:
在调用私有方法前应该设置该方法是可访问的
使用反射调用静态方法:
静态不属于任何对象,静态方法属于类本身
此时把invoke()方法的第一个参数设置为null即可
当方法需要一个数组参数时:
String[]这里不行是因为进行了自动解包,导致变成了一个一个的字符串。而不是字符串数组
其他的API:
Class类中:
int getModifiers()获得修饰符
String getName()返回类的全限定名
Package getPackage()获得该类的包
String getSimpleName()获取类的简单名字
Class getSupperclass()获得类的父类
boolean isArray()判断该class实例是否是数组
boolean isEnum()判断class实例是否是枚举
Class类,Constructor类,Method类,Filed类