本文主要介紹的是枚舉類,注解和反射。還有一些基礎知識:static,基本資料類型,運算符優先級放在文中,以便查閱複習。
其中牽扯到泛型的部分,可參考本人的另一篇部落格:(Collection, List, 泛型)JAVA集合架構一
1. static關鍵字
static可以修飾的有:屬性,方法,代碼塊,内部類。
按是否用static修飾分為靜态屬性和非靜态屬性(執行個體變量)。
非靜态屬性(執行個體變量):當建立了類的多個對象,每個對象都獨立擁有自己的非靜态屬性。當修改其中一個對象中的非靜态屬性時,不會改變其他對象中的非靜态屬性。
靜态屬性(靜态變量):當建立了類的多個對象,多個對象共享同一個靜态對象。通過任一個對象改變靜态屬性,所有對象的靜态屬性都會發生改變。
靜态變量随着類的加載而加載。可通過class.靜态變量進行調用。
靜态變量的加載早于對象的建立,在建立對象的過程中,才實作執行個體屬性的加載。
由于類隻會加載一次,則靜态變量在記憶體中也隻會存在一份。存在方法區的靜态域中。
靜态方法:
随着類的加載而加載,可以直接通過類.靜态方法調用
靜态方法中,隻能調用靜态的方法或屬性,因為它們生命周期相同;非靜态方法中,既可以調用非靜态的方法或屬性,也可以調用靜态的方法或屬性。
注意點:
在靜态的方法内,不能使用this和super關鍵字,因為靜态方法不需要執行個體化對象,而沒有執行個體化對象this就沒有意義。一定要是同級的生命周期才能使用。2. 枚舉類
JDK5.0新增enum關鍵字
了解:
類的對象隻有有限個、确定的,稱此類為枚舉類
當需要定義一組常量時,建議使用枚舉類
常用方法:

重點掌握:toString,values,valueOf
情況一:實作接口,在enum類中實作抽象方法
情況二:讓枚舉類的對象分别實作接口中的抽象方法
整體demo包含常用方法的使用:
Thread中線程狀态利用的就是枚舉類,可參考源碼。
3. 注釋和注解
注解(Annotation)是代碼裡的特殊标記,這些标記可以在編譯,類加載,運作時被讀取,并執行相應的處理。通過使用注解,程式員可以在不改變原有邏輯的情況下,在源檔案中嵌入一些補充資訊。代碼分析工具、開發工具和部署工具可以通過這些補充資訊進行驗證或進行部署。JDK5.0新增
在JavaSE中注解的使用目的比較簡單,比如标記過時功能,忽略警告等。在JavaEE中占據了更重要的角色。後續部落格将會繼續JavaEE的内容。
在一定程度上,架構 = 注解 + 反射 + 設計模式
類注釋必須放在import語句之後,類定義之前。
除了通用标記之外,還可以使用下面的标記:
@param變量描述,這個标記将對目前方法的參數部分添加一個條目。這個描述可以占據多行,并可以使用HTML标記,一個方法的所有變量描述需要放在一起。
@return描述
@throws類描述,表示這個方法有可能抛出異常。
注意,一定要用 # 分隔類名和方法名,或類名和變量名。
注解聲明為:@interface
内部定義成員,通常用value表示
可以指定成員的預設值,使用default定義
如果自定義注解裡沒有成員,表明是一個辨別作用
具體用途在反射和架構中。自定義注解必須配上注解的資訊處理流程(使用反射)才有意義。
元注解:用于修飾其他注解定義
例:
JDK5.0提供了4個标準的元注解:
Retention, Target, Documented, Inherited
自定義注解通常都會使用以上兩個元注解Retention, Target。
Repeatable()
其中,MyAnnotation和MyAnnotations需要保持Retention和Target以及Inherited一緻,在這部分隻需要注意,在以後用到時再重點講解。
4. 反射
反射機制提供的功能:
運作時判斷任意一個對象所屬的類
運作時構造任意一個類的對象
運作時判斷任意一個類所具有的成員變量和方法
運作時擷取泛型資訊
運作時調用任意一個對象的成員變量和方法
在運作時處理注解
生成動态代理
關于java.lang.Class類的了解:
類的加載過程:程式經過javac.exe指令後(編譯),會生成一個或多個位元組碼檔案(.class檔案)。接着使用java.exe指令對某個位元組碼檔案進行解釋運作。相當于将某個位元組碼檔案加載到記憶體中,此過程成為類的加載。加載到記憶體中的類,稱為運作時類,此運作時類,作為Class的一個執行個體。
Class的執行個體對應着一個運作時類
加載到記憶體中的運作時類,會緩存一定的時間。在此時間内,可以通過不同方式來擷取Class的執行個體。
Object是所有類的父類,而Class是類的類。
三種Class執行個體的擷取方式:
擷取目前對象的類型對象,類型類是指代表一個類型的類,擷取class對象的方法有:1.類名.class,所有的引用資料類型和基本資料類型都可以通過這個方式擷取。2.通過對象執行個體.getClass()來獲得class對象。3.調用Class的靜态方法 Class.forName(String classPath)
此外,還可以使用類的加載器ClassLoader,不再詳細贅述。
JDK8中對于自定義類的ClassLoader屬于系統類加載器,此外還有擴充類加載器和引導類加載器。
簡述下方的Person類:内部成員變量為public String name, private int age, 有公有構造器和私有構造器,有公有方法show()和私有方法show1(), 重寫toString。
基本應用demo:
需要注意的是Class對象并不能指明該類型的執行個體化,需要在Field或Method這種将執行個體放入參數中。
通過反射,可以調用Person類的私有結構,如:私有構造器,私有方法,私有屬性。
這裡和面向對象概念中的封裝性可能有沖突,為什麼要利用反射呢?
舉個例子:反射具有動态性的特征。背景中,伺服器的程式一直運作,假如從前端傳來資訊,背景就可以動态進行調用。動态過程中,可以利用反射進行應用。
獲得方法結構:
擷取方法的内部結構:
構造器等都類似,不再贅述。構造器的.getConstructors和.getDeclaredConstructors不能擷取父類的結構,沒有意義。
此外還可擷取運作時類的父類和父類的泛型,運作時類的接口,包,注釋等,代碼比較機械,不再贅述。
調用運作時類的屬性:
調用運作時類中指定的方法:
如果調用的運作時類的方法沒有傳回值,則傳回null
調用運作時類中指定的構造器:
需要注意的是即使Class加上泛型聲明,下方的Constructor.newInstance仍需強轉
接下來是最近刷題時總結了一些基礎知識,需要對這些資料保持敏感。
5. 基本資料類型
byte:
1個位元組,8位、有符号的,以二進制補碼表示的整數;
最小值是 -128(-2^7);
最大值是 127(2^7-1);
預設值是 0;
byte 類型用在大型數組中節約空間,主要代替整數,因為 byte 變量占用的空間隻有 int 類型的四分之一;
例子:byte a = 100,byte b = -50。
short:
2個位元組,16 位、有符号的以二進制補碼表示的整數
最小值是 -32768(-2^15);
最大值是 32767(2^15 - 1);
Short 資料類型也可以像 byte 那樣節省空間。一個short變量是int型變量所占空間的二分之一;
例子:short s = 1000,short r = -20000。
int:整數型,4個位元組32位,負數以補碼形式存在,取值範圍如下:
最小值是 -2,147,483,648(-2^31);
最大值是 2,147,483,647(2^31 - 1);
預設值為0
long:
8個位元組, 64 位、有符号的以二進制補碼表示的整數;
最小值是 -9,223,372,036,854,775,808(-2^63);
最大值是 9,223,372,036,854,775,807(2^63 -1);
這種類型主要使用在需要比較大整數的系統上;
預設值是 0L;
例子: long a = 100000L,Long b = -200000L。
"L"理論上不分大小寫,但是若寫成"l"容易與數字"1"混淆,不容易分辯。是以最好大寫。
float:
float 資料類型是單精度、32位、符合IEEE 754标準的浮點數;
float 在儲存大型浮點數組的時候可節省記憶體空間;
預設值是 0.0f;
浮點數不能用來表示精确的值,如貨币;
例子:float f1 = 234.5f。
double:
double 資料類型是雙精度、64 位、符合 IEEE 754 标準的浮點數;
浮點數的預設類型為 double 類型;
double類型同樣不能表示精确的值,如貨币;
預設值是 0.0d;
boolean:
boolean資料類型表示一位的資訊;
隻有兩個取值:true 和 false;
這種類型隻作為一種标志來記錄 true/false 情況;
預設值是 false;
例子:boolean one = true。
char:
char 類型是一個單一的 16 位 Unicode 字元;
最小值是 \u0000(左方是16進制表示,十進制等效值為 0);
最大值是 \uffff(即為 65535);
char 資料類型可以儲存任何字元;
例子:char letter = 'A';。
6. 運算符優先級