【Java】【類和物件】內部類的簡單應用
阿新 • • 發佈:2021-01-02
註解java.Annotation
什麼是註解
- Annotation是從JDK5開始引入的新技術.
- Annotation的作用:
- 不是程式本身,可以對程式作出解釋.(這一-點和註釋(comment)沒什麼區別)
- 可以被其他程式(比如:編譯器等)讀取.
- Annotation的格式:
- 註解是以"@註釋名"在程式碼中存在的,還可以新增一-些引數值,例
- 如:@SuppressWarnings(value="unchecked").
- Annotation在哪裡使用?
- 可以附加在package , class , method , field等上面,相當於給他們添加了額外的輔助資訊,
- 我們可以通過反射機制程式設計實現對這些元資料的訪問
內建註解
- @Override :定義在java.lang.Override中,此註釋只適用於修辭方法,表示一個方法宣告打算重寫超類中的另一個方法宣告.
- @Deprecated :定義在java.lang.Deprecated中,此註釋可以用於修辭方法,屬性,類,表示不鼓勵程式設計師使用這樣的元素,通常是因為它很危險或者存在更好的選擇.
- @SuppressWarnings : 定義在java.lang.SuppressWarnings中,用來抑制編譯時的警告資訊.
- 與前兩個註釋有所不同,需要新增一個引數才能正確使用,這些引數都是已經定義好的,選擇性的使用就好了.
- @SuppressWarnings("ll")
- @SuppressWarnings("unchecked")
- @SuppressWarnings(value={"unchecked","deprecation"})
- ……
元註解
- 元註解的作用就是負責註解其他註解, Java定義了4個標準的meta-annotation型別,他們被用來提供對其他annotation型別作說明.
- 這些型別和它們所支援的類在java.lang.annotation包中可以找到(@Target , @Retention,@Documented , @Inherited )
- @Target :用於描述註解的使用範圍(即:被描述的註解可以用在什麼地方)
- @Retention :表示需要在什麼級別儲存該註釋資訊,用於描述註解的生命週期
- (SOURCE < CLASS < RUNTIME)
- @Document: 說明該註解將被包含在javadoc中
- @Inherited: 說明子類可以繼承父類中的該註解
自定義註解
- 使用@interface自定義註解時,自動繼承了java.lang.annotation.Annotation介面
- 分析:
- @ interface用來宣告一個註解,格式: public @ interface註解名{定義內容}
- 其中的每-一個方法實際上是聲明瞭一個配置引數.
- 方法的名稱就是引數的名稱.
- 返回值型別就是引數的型別(返回值只能是基本型別,Class , String , enum ).
- 可以通過default來宣告引數的預設值
- 如果只有一個引數成員, 一般引數名為value
- 註解元素必須要有值,我們定義註解元素時, 經常使用空字串,0作為預設值.
反射 java.Reflection
動態 VS 靜態語言
- 動態語言
- 是一類在執行是可以改變其結構的語言,是可以在執行時程式碼可以根據某些條件改變自身結構
- 主要的動態語言:Object-C,C#,javascript ,PHP Python……
- 靜態語言
- 與動態語言相對應的,執行時結構不可以變的語言就是靜態語言,如C,C++
- JAVA 不是動態語言,但Java可以稱之為“準動態語言”。即Java有一定的動態性,可以利用反射機制活的類似動態語言的特效。Java的動態性讓程式設計的時候更加靈活
反射概述 Reflection
-
Reflection (反射)是Java被視為動態語言的關鍵,反射機制允許程式在執行期藉助於Reflection API取得任何類的內部資訊,並能直接操作任意物件的內部屬性及方法。
-
Class C = Class forName("java.lang.String")
-
載入完類之後,在堆記憶體的方法區中就產生了一個Class型別的物件(一個類只有一個Class物件),這個物件就包含了完整的類的結構資訊。可以通過這個物件看到類的結構。這個物件就像一面鏡子,透過這個鏡子看到類的結構,所以形象的稱之為:反射
Java 反射機制研究及應用
- Java反射機制提供的功能
- 執行時判斷任意一個物件所屬的類
- 執行時構造任意一個類的物件
- 執行時判斷任意一個類所有具有的成員變數和方法
- 執行時獲取泛型資訊
- 執行時呼叫任意一個物件的成員變數和方法
- 執行時處理註解
- 生成動態代理
- ……
優缺點
-
優點:可以實現動態建立物件和編譯,體現出很大的靈活性
-
缺點:對效能有影響,使用反射基本上是一種解釋操作,可以告訴JVM,希望做什麼並且它滿足我的需求。這類操作總是慢於直接執行相同的操作
Class 類
-
物件照鏡子後可以得到的資訊:某個類的屬性、方法和構造器、某個類到底實現了哪些介面對於每個類而言,JRE都為其保留一個不變的Class型別的物件。一個Class物件包含了特定某個結構(class/interface/enum/annotation/primitive type/void/D)的有關資訊。
-
Class 本身也是一個類
-
Class物件只能由系統建立物件
-
一個載入的類在JVM中只會有一個Class例項
-
一個Class物件對應的是一個載入到JVM中的一個.class檔案
-
每個類的例項都會記得自己是由哪個Class例項所生成
-
通過Class可以完整地得到一個類中的所有被載入的結構
-
Class類 是Reflection的根源,針對任何你想動態載入、執行的類,唯有先獲得相應的Class物件
class類的常用方法
方法名 | 功能說明 |
---|---|
static ClassForName(String name) | 返回指定類名name的Class物件 |
Object NewInstance() | 呼叫預設建構函式,返回Class物件的一個例項 |
getName() | 返回此Class物件所表示的實體(類,介面,陣列類或Void)的名稱 |
Class getSuprClass() | 返回當前Class的物件的父類的Class物件 |
Class[] getInterfaces() | 獲取當前Class物件的介面 |
ClassLoader getClassLoader() | 返回該類的類載入器 |
Constructor[] getConstructors() | 返回一個包含某些Constructor物件的陣列 |
Method getMother(String name,Class.. T) | 返回一個Method物件,此物件的形參型別為paramType |
Field[] getDeclaredFields() | 返回Field 物件的一個數組 |
類載入器的作用
- 類載入的作用:將class檔案位元組碼內容載入到記憶體中,並將這些靜態資料轉換成方法區的執行時資料結構,然後在堆中生成一個代表這個類的java.lang.Class物件, 作為方法區中類資料的訪問入口。
- 類快取:標準的JavaSE類載入器可以按要求查詢類,但一旦某個類被載入到類載入器中,它將維持載入(快取)一段時間。不過JVM垃圾回收機制可以回收這些Class物件
- 類載入器作用是用來把類(class)裝載進記憶體的。
獲取執行時類的完整結構
- 通過反射獲取執行時類的完整結構
- Field、Method、 Constructor、 Superclass、 Interface、 Annotation
- 實現的全部介面.
- 所繼承的父類
- 全部的構造器
- 全部的方法
- 全部的Field
- 註解
- ……
反射操作泛型
- Java採用泛型擦除的機制來引入泛型, Java中的泛型僅僅是給編譯器javac使用的,確保資料的安全性和免去強制型別轉換問題,但是, 一旦編譯完成,所有和泛型有關的型別全部擦除
- 為了通過反射操作這些型別, Java新增了ParameterizedType , GenericArrayType,TypeVariable和WildcardType幾種型別來代表不能被歸一到Class類中的型別但是又和原始型別齊名的型別.
- ParameterizedType :表示一種引數化型別,比如Collection
- GenericArrayType :表示一種元素型別是引數化型別或者型別變數的陣列型別
- TypeVariable :是各種型別變數的公共父介面
- WildcardType :代表- -種萬用字元型別表示式
反射操作註解
- getAnnotations
- getAnnotation