一、類加載
應用程式的啟動: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文檔中顯示注解資訊