Java註解和反射---初識註解反射
註解:
元註解:負責註解其他註解
主要的元註解為:
@Target:用於描述註解的使用範圍(被描述的註解可以用在那個地方)
TYPE表示當前註解在類中有效,METHOD表示當前註解在方法中有效
@Retention:用於描述註解的生命週期(SOURCE<CLASS<RUNTION)
SOURCE:表示在原始檔中當java檔案被編譯成class檔案時就被遺棄了
CLASS:表示被保留在class檔案,但jvm載入class檔案就被遺棄了,這是預設的生命週期
RUNTION:表示執行時有效,該值的生命週期大於前兩種
@Document:說明該註解將被包含在javadoc中
@Inherited:說明子類可以具有父類的註解
自定義註解:@interface自定義註解時,自動繼承了java.lang.annontation.Annontation介面
自定義註解使用@interface自定義註解,儘量在自定義註解上加入兩個元註解聲明當前註解可以在哪裡使用@Target和當前註解的生命週期@Retention
反射
什麼是反射:反射是java被視為動態語言的關鍵,反射機制允許程式在執行期藉助於Reflection API取得任何類的內部資訊,並能直接操作任何物件的內部屬性及其方法
載入完類之後,在堆記憶體中就產生了一個Class型別的物件(一個類只有一個Class物件),這個物件就包含了完整的類的結構資訊。我們可以通過這個物件看到類的結構。一個類在記憶體中只有一個Class物件
雖然反射很強大但它也是有缺點的,物件效能是有影響的,使用反射基本上是一種解釋操作,就是我們告訴虛擬機器jvm,我們希望做什麼並且它滿足我們什麼要求。這類操作總是慢於直接執行相同操作。說完了缺點我們在來看看他的優點,可以動態建立物件和編譯,體現出很大的靈活性。
既然我們知道了反射是什麼那我們就來看個demo體會一下反射吧
我們先建立一個類user
class user{ private String name; private String age; private int id; public user() { } public user(String name, String age, int id) { this.name = name; this.age = age; this.id = id; } }
通過反射forName拿到他的Class物件
public class TestReflect { public static void main(String[] args) throws ClassNotFoundException { //通過反射獲得類的Class物件 Class forName = Class.forName("com.ssl.Test.user"); System.out.println(forName); } }
那我們來看看執行的結果吧
光這個一個是不是還沒有體現一個類在記憶體中只有一個Class物件這句話呢?
public class TestReflect {
public static void main(String[] args) throws ClassNotFoundException {
//通過反射獲得類的Class物件
Class c1 = Class.forName("com.ssl.Test.user");
Class c2 = Class.forName("com.ssl.Test.user");
Class c3 = Class.forName("com.ssl.Test.user");
Class c4 = Class.forName("com.ssl.Test.user");
/**
* 這裡我們用到了小學二年級學到的hashCode()方法體現是同一個Class物件
*/
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());
}
}
到這裡我們是不是就理解了一個類在記憶體中只有一個Class物件這句話了呢?
其實獲得Class物件的方式還有很多。。。。(下次再說吧)