一、类加载
应用程序的启动:java 类名——>调用JVM,启动JVM进程,启动mian主线程,加载主类。
应用程序的结束:1、所有代码执行完毕;2、存在没有处理的Exception、Error;3、System.exit(0);4、运行平台强制结束。
1、类的生命周期
(1)加载:把类的字节码文件加载到JVM的内存方法区中并且生成一个Class类型的对象。
ClassLoader(类加载器)加载(通过流的技术,也可自定义类记载器), 生成Class类型对象,通过Class类的方法操作类的属性、方法、构造器。
(2)连接:a、验证-字节码文件格式是否正确;b、准备-为类变量(静态变量)分配空间,默认初始化;c、解析-把符号引用替换成直接引用(指针:指向内存地址)。
(3)初始化:当类被主动使用时,为类变量进行声明处和静态块处初始化。
1、当虚拟机Java命令运行启动类;
2、当创建某个类的新实例时;
3、当调用某个类的静态成员;
4、当初始化某个子类时,该子类的所有父类都会被初始化;
5、当使用反射方法强制创建某个类或接口的对象时; Demo.class.newInstance();
static final类型不能导致初始化;
(4)使用
(5)卸载
2、类加载器
根类加载器<——扩展类加载器<——系统类加载器<——自定义类加载器
根类加载器:加载核心类库,d:\java\jdk1.8.0_144\jre\lib,c++写的,显示为null。
扩展类加载器:加载扩展类库,lib\ext。
系统类加载器:应用类加载器,classpath路径下的类。
自定义类加载器:不是classpath路径,自己指定路径。
父类委托机制(双亲):
调用ClassLoader后,通过Class<?> c=findLoadedClass(name)查找此类是否被加载,已加载返回Class对象,未加载返回null;未加载,系统类加载器先不加载,查看父类加载器(扩展类加载器)是否存在,父类递归调用父类(根类加载器)加载,如根类加载器不存在,扩展类加载器加载,扩展类加载器不存在,系统类加载器加载。
1、获得系统类加载器:ClassLoader.getSystemClassLoader().loadClass("包名.类名");
2、加载并初始化:Class.forName("包名.类名",true,ClassLoader.getSystemClassLoader());true表示进行初始化,后面是指定加载器。
Class.forName("包名.类名");
自定义加载器:
自定义类,属性为类的路径——>继承ClassLoader,重写findClass方法(用流把.class文件读出来、解析成方法区数据结构);
ClassLoader类的defineClass(name,b[ ],0,len)将一个byte数组转换为Class类的实例;
Class类的forName(name类的完全限定名,true初始化类,loader加载器)返回类关联的Class对象;
FileInputStream类的read(byte[ ] b)从输入流中读入数组,返回读入的字节总数;
二、反射
反射是从方法区的字节码中动态的获得类中的信息。
获得 类名. class 对应的Class对象:
a、Class<?> c=Class.forName("包名 . 类名");
b、Class<类名> c=类名 . class;
c、Class<? extends 类名> c=new 类名( ). getClass( );
1、获取属性
Field [ ] fs=c.getDeclaredFields( );包括私有的>>区别于 Field [ ] fs=c.getFields( );获得属性不包括私有的。
f.setAccessible(true);设置访问权限 ,也可通过安全管理器设置 System.setSecurityManager(new SecurityManager);
2、获取方法
Method [ ] m=c.getDeclaredMethods( );
Method类的invoke( )调用方法
3、获得构造器
Constructor cr=c.getDeclaredConstructor(参数类型.class);
cr.newInstance(传值);
4、获得注解
Annotation [ ] an=c.getDeclaredAnnotations( );
Arrays.stream( an ) . forEach( System.out ::println);
用反射获得 子类 继承父类注解:
Class<子类名> cs=子类名 . class;
Annotation [ ] ans=cs . getField( "属性名") . getAnnotations( );//不用getDeclaredAnnotations( )
Arrays.stream( ans) . forEach( System.out ::println);
三、注解
@Overridec 重写
@FunctionalInterface 函数式接口
@Deprecated 已过时、过期
@SuppressWarnings 镇压警告 -all rawtypes、unused 原生类型,变量声明了,没有使用 unchecked 没有进行类型检查 serial 版本号
自定义注解:@interface 注解名{ public/默认 类型 成员名( ) default 默认值;}
Java元注解:@Target(ElementType . xxx),ElementType:CONSTRUCTOR 构造方法声明;FIELD字段声明(包括枚举常量);LOCAL_VARIABLE 局部变量声明;METHOD 方法声明;PACKAGE 包声明;PARAMETER 参数声明;TYPE 类、接口(包括注释类型)或枚举声明。
@Retention( )注解保留时间,RetentionPolicy . SOURCE/CLASS/RUNTIME
@Inherited( )子类可以继承类 类型声明时的注解
@Documented( )在生成的javadoc命令的API文档中显示注解信息