天天看點

Java枚舉類、注解和反射

本文主要介紹的是枚舉類,注解和反射。還有一些基礎知識:static,基本資料類型,運算符優先級放在文中,以便查閱複習。

其中牽扯到泛型的部分,可參考本人的另一篇部落格:(Collection, List, 泛型)JAVA集合架構一

1. static關鍵字

static可以修飾的有:屬性,方法,代碼塊,内部類。

按是否用static修飾分為靜态屬性和非靜态屬性(執行個體變量)。

非靜态屬性(執行個體變量):當建立了類的多個對象,每個對象都獨立擁有自己的非靜态屬性。當修改其中一個對象中的非靜态屬性時,不會改變其他對象中的非靜态屬性。

靜态屬性(靜态變量):當建立了類的多個對象,多個對象共享同一個靜态對象。通過任一個對象改變靜态屬性,所有對象的靜态屬性都會發生改變。

靜态變量随着類的加載而加載。可通過class.靜态變量進行調用。

靜态變量的加載早于對象的建立,在建立對象的過程中,才實作執行個體屬性的加載。

由于類隻會加載一次,則靜态變量在記憶體中也隻會存在一份。存在方法區的靜态域中。

靜态方法:

随着類的加載而加載,可以直接通過類.靜态方法調用

靜态方法中,隻能調用靜态的方法或屬性,因為它們生命周期相同;非靜态方法中,既可以調用非靜态的方法或屬性,也可以調用靜态的方法或屬性。

注意點:

在靜态的方法内,不能使用this和super關鍵字,因為靜态方法不需要執行個體化對象,而沒有執行個體化對象this就沒有意義。一定要是同級的生命周期才能使用。2. 枚舉類

JDK5.0新增enum關鍵字

了解:

類的對象隻有有限個、确定的,稱此類為枚舉類

當需要定義一組常量時,建議使用枚舉類

常用方法:

Java枚舉類、注解和反射

重點掌握:toString,values,valueOf

情況一:實作接口,在enum類中實作抽象方法

情況二:讓枚舉類的對象分别實作接口中的抽象方法

整體demo包含常用方法的使用:

Thread中線程狀态利用的就是枚舉類,可參考源碼。

3. 注釋和注解

注解(Annotation)是代碼裡的特殊标記,這些标記可以在編譯,類加載,運作時被讀取,并執行相應的處理。通過使用注解,程式員可以在不改變原有邏輯的情況下,在源檔案中嵌入一些補充資訊。代碼分析工具、開發工具和部署工具可以通過這些補充資訊進行驗證或進行部署。JDK5.0新增

在JavaSE中注解的使用目的比較簡單,比如标記過時功能,忽略警告等。在JavaEE中占據了更重要的角色。後續部落格将會繼續JavaEE的内容。

在一定程度上,架構 = 注解 + 反射 + 設計模式

Java枚舉類、注解和反射

類注釋必須放在import語句之後,類定義之前。

除了通用标記之外,還可以使用下面的标記:

@param變量描述,這個标記将對目前方法的參數部分添加一個條目。這個描述可以占據多行,并可以使用HTML标記,一個方法的所有變量描述需要放在一起。

@return描述

@throws類描述,表示這個方法有可能抛出異常。

Java枚舉類、注解和反射
注意,一定要用 # 分隔類名和方法名,或類名和變量名。

注解聲明為:@interface

内部定義成員,通常用value表示

可以指定成員的預設值,使用default定義

如果自定義注解裡沒有成員,表明是一個辨別作用

具體用途在反射和架構中。自定義注解必須配上注解的資訊處理流程(使用反射)才有意義。

Java枚舉類、注解和反射

元注解:用于修飾其他注解定義

例:

JDK5.0提供了4個标準的元注解:

Retention, Target, Documented, Inherited

Java枚舉類、注解和反射
Java枚舉類、注解和反射

自定義注解通常都會使用以上兩個元注解Retention, Target。

Java枚舉類、注解和反射

Repeatable()

其中,MyAnnotation和MyAnnotations需要保持Retention和Target以及Inherited一緻,在這部分隻需要注意,在以後用到時再重點講解。

Java枚舉類、注解和反射

4. 反射

Java枚舉類、注解和反射

反射機制提供的功能:

運作時判斷任意一個對象所屬的類

運作時構造任意一個類的對象

運作時判斷任意一個類所具有的成員變量和方法

運作時擷取泛型資訊

運作時調用任意一個對象的成員變量和方法

在運作時處理注解

生成動态代理

關于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屬于系統類加載器,此外還有擴充類加載器和引導類加載器。

Java枚舉類、注解和反射

簡述下方的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. 運算符優先級

Java枚舉類、注解和反射

繼續閱讀