JAVA反射
動(dòng)態(tài)語(yǔ)言,是指程序在運(yùn)行時(shí)可以改變其結(jié)構(gòu):新的函數(shù)可以引進(jìn),已有的函數(shù)可以被刪除等結(jié)構(gòu)上的變化。比如常見(jiàn)的JavaScript 就是動(dòng)態(tài)語(yǔ)言,除此之外Ruby,Python 等也屬于動(dòng)態(tài)語(yǔ)言,而C、C++則不屬于動(dòng)態(tài)語(yǔ)言。從反射角度說(shuō)JAVA 屬于半動(dòng)態(tài)語(yǔ)言
1 反射機(jī)制概念
(運(yùn)行狀態(tài)中知道類(lèi)所有的屬性和方法)
在Java 中的反射機(jī)制是指在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi)都能夠知道這個(gè)類(lèi)所有的屬性和方法;并且對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法;這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能成為Java 語(yǔ)言的反射機(jī)制。
2 反射的應(yīng)用場(chǎng)合
在Java 程序中許多對(duì)象在運(yùn)行是都會(huì)出現(xiàn)兩種類(lèi)型:編譯時(shí)類(lèi)型和運(yùn)行時(shí)類(lèi)型。編譯時(shí)的類(lèi)型由聲明對(duì)象時(shí)實(shí)用的類(lèi)型來(lái)決定,運(yùn)行時(shí)的類(lèi)型由實(shí)際賦值給對(duì)象的類(lèi)型決定。如:
Person p=new Student();
其中編譯時(shí)類(lèi)型為Person,運(yùn)行時(shí)類(lèi)型為Student。
的編譯時(shí)類(lèi)型無(wú)法獲取具體方法
程序在運(yùn)行時(shí)還可能接收到外部傳入的對(duì)象,該對(duì)象的編譯時(shí)類(lèi)型為Object,但是程序有需要調(diào)用該對(duì)象的運(yùn)行時(shí)類(lèi)型的方法。為了解決這些問(wèn)題,程序需要在運(yùn)行時(shí)發(fā)現(xiàn)對(duì)象和類(lèi)的真實(shí)信息。然而,如果編譯時(shí)根本無(wú)法預(yù)知該對(duì)象和類(lèi)屬于哪些類(lèi),程序只能依靠運(yùn)行時(shí)信息來(lái)發(fā)現(xiàn)該對(duì)象和類(lèi)的真實(shí)信息,此時(shí)就必須使用到反射了。
3 Java 反射API
反射API 用來(lái)生成JVM 中的類(lèi)、接口或則對(duì)象的信息。
1. Class 類(lèi):反射的核心類(lèi),可以獲取類(lèi)的屬性,方法等信息。
2. Field 類(lèi):Java.lang.reflec 包中的類(lèi),表示類(lèi)的成員變量,可以用來(lái)獲取和設(shè)置類(lèi)之中的屬性值。
3. Method 類(lèi):Java.lang.reflec 包中的類(lèi),表示類(lèi)的方法,它可以用來(lái)獲取類(lèi)中的方法信息或者執(zhí)行方法。
4. Constructor 類(lèi):Java.lang.reflec 包中的類(lèi),表示類(lèi)的構(gòu)造方法。
3.1 反射使用步驟
(獲取Class 對(duì)象、調(diào)用對(duì)象方法)
1. 獲取想要操作的類(lèi)的Class 對(duì)象,他是反射的核心,通過(guò)Class 對(duì)象我們可以任意調(diào)用類(lèi)的方法。
2. 調(diào)用Class 類(lèi)中的方法,既就是反射的使用階段。
3. 使用反射API 來(lái)操作這些信息。
3.2 獲取Class 對(duì)象的3 種方法
調(diào)用某個(gè)對(duì)象的getClass()方法
Person p=new Person();
Class clazz=p.getClass();
調(diào)用某個(gè)類(lèi)的class 屬性來(lái)獲取該類(lèi)對(duì)應(yīng)的Class 對(duì)象
Class clazz=Person.class;
使用Class 類(lèi)中的forName()靜態(tài)方法(最安全/性能最好)
Class clazz=Class.forName("類(lèi)的全路徑"); (最常用)
當(dāng)我們獲得了想要操作的類(lèi)的Class 對(duì)象后,可以通過(guò)Class 類(lèi)中的方法獲取并查看該類(lèi)中的方法和屬性。
3.3 創(chuàng)建對(duì)象的兩種方法
Class 對(duì)象的newInstance()
1. 使用Class 對(duì)象的newInstance()方法來(lái)創(chuàng)建該Class 對(duì)象對(duì)應(yīng)類(lèi)的實(shí)例,但是這種方法要求該Class 對(duì)象對(duì)應(yīng)的類(lèi)有默認(rèn)的空構(gòu)造器。
調(diào)用Constructor 對(duì)象的newInstance()
2. 先使用Class 對(duì)象獲取指定的Constructor 對(duì)象,再調(diào)用Constructor 對(duì)象的newInstance() 方法來(lái)創(chuàng)建Class 對(duì)象對(duì)應(yīng)類(lèi)的實(shí)例,通過(guò)這種方法可以選定構(gòu)造方法創(chuàng)建實(shí)例。
2JAVA 注解
Annotation(注解)是Java 提供的一種對(duì)元程序中元素關(guān)聯(lián)信息和元數(shù)據(jù)(metadata)的途徑和方法。Annatation(注解)是一個(gè)接口,程序可以通過(guò)反射來(lái)獲取指定程序中元素的Annotation 對(duì)象,然后通過(guò)該Annotation 對(duì)象來(lái)獲取注解中的元數(shù)據(jù)信息。
2.1 四種標(biāo)準(zhǔn)元注解
元注解的作用是負(fù)責(zé)注解其他注解。Java5.0 定義了4 個(gè)標(biāo)準(zhǔn)的meta-annotation 類(lèi)型,它們被用來(lái)提供對(duì)其它annotation 類(lèi)型作說(shuō)明。
2.1.1 @Target 修飾的對(duì)象范圍
@Target說(shuō)明了Annotation所修飾的對(duì)象范圍:Annotation可被用于packages、types(類(lèi)、接口、枚舉、Annotation 類(lèi)型)、類(lèi)型成員(方法、構(gòu)造方法、成員變量、枚舉值)、方法參數(shù)和本地變量(如循環(huán)變量、catch 參數(shù))。在Annotation 類(lèi)型的聲明中使用了target 可更加明晰其修飾的目標(biāo)
2.1.2 @Retention 定義被保留的時(shí)間長(zhǎng)短
Retention 定義了該Annotation 被保留的時(shí)間長(zhǎng)短:表示需要在什么級(jí)別保存注解信息,用于描述注解的生命周
期(即:被描述的注解在什么范圍內(nèi)有效),取值(RetentionPoicy)由:
在源文件中有效(即源文件保留)
在class 文件中有效(即class 保留)
在運(yùn)行時(shí)有效(即運(yùn)行時(shí)保留)
2.1.3 @Documented 描述-javadoc
@ Documented 用于描述其它類(lèi)型的annotation 應(yīng)該被作為被標(biāo)注的程序成員的公共API,因此可以被例如javadoc 此類(lèi)的工具文檔化。
2.1.4 @Inherited 闡述了某個(gè)被標(biāo)注的類(lèi)型是被繼承的
@Inherited 元注解是一個(gè)標(biāo)記注解,@Inherited 闡述了某個(gè)被標(biāo)注的類(lèi)型是被繼承的。如果一個(gè)使用了@Inherited 修飾的annotation 類(lèi)型被用于一個(gè)class,則這個(gè)annotation 將被用于該class 的子類(lèi)。
2.2 注解處理器
如果沒(méi)有用來(lái)讀取注解的方法和工作,那么注解也就不會(huì)比注釋更有用處了。使用注解的過(guò)程中,很重要的一部分就是創(chuàng)建于使用注解處理器。Java SE5 擴(kuò)展了反射機(jī)制的API,以幫助程序員快速的構(gòu)造自定義注解處理器。
要想學(xué)習(xí)JAVA,反射和注解這些都是基本的要求,希望大家能夠喜歡,






