Java的作用
反射通常由程序使用,這些程序需要能夠檢查或修改在Java虛擬機(jī)中運(yùn)行的應(yīng)用程序的運(yùn)行時(shí)行為,這是一個(gè)相對(duì)高級(jí)的功能,只有那些掌握了語(yǔ)言基礎(chǔ)知識(shí)的開發(fā)人員才能使用??紤]到這一點(diǎn),反射是一種強(qiáng)大的技術(shù),可以使應(yīng)用程序執(zhí)行本來(lái)不可能的操作。
1. 可擴(kuò)展性
應(yīng)用程序可以通過(guò)使用完全限定名稱創(chuàng)建可擴(kuò)展性對(duì)象的實(shí)例來(lái)使用外部的用戶定義類。
2. 類瀏覽器和可視化開發(fā)環(huán)境
類瀏覽器需要能夠枚舉類的成員??梢暬_發(fā)環(huán)境可以從利用反射中可用的類型信息中受益,以幫助開發(fā)人員編寫正確的代碼。
3. 調(diào)試器和測(cè)試工具
調(diào)試器需要能夠檢查類上的私有成員。測(cè)試工具可以利用反射系統(tǒng)地調(diào)用類上定義的可發(fā)現(xiàn)的set API,以確保測(cè)試套件中的高級(jí)代碼覆蓋率。
反射的缺點(diǎn)
反射是強(qiáng)大的,但不應(yīng)隨意使用。如果可以在不使用反射的情況下執(zhí)行操作,則優(yōu)選避免使用它。通過(guò)反射訪問(wèn)代碼時(shí),應(yīng)牢記以下問(wèn)題。
1. 績(jī)效開銷
由于反射涉及動(dòng)態(tài)解析的類型,因此無(wú)法執(zhí)行某些Java虛擬機(jī)優(yōu)化。因此,反射操作的性能低于非反射操作,并且應(yīng)避免在性能敏感應(yīng)用程序中頻繁調(diào)用的代碼段中。
2. 安全限制
反射需要運(yùn)行時(shí)權(quán)限,在安全管理器下運(yùn)行時(shí)可能不存在。對(duì)于必須在受限安全上下文中運(yùn)行的代碼,例如在Applet中,這是一個(gè)重要的考慮因素。
3. 內(nèi)部接觸
由于反射允許代碼執(zhí)行在非反射代碼中非法的操作,例如訪問(wèn)private字段和方法,因此使用反射會(huì)導(dǎo)致意外的副作用,這可能導(dǎo)致代碼功能失常并可能破壞可移植性。反射代碼打破了抽象,因此可能會(huì)通過(guò)升級(jí)平臺(tái)來(lái)改變行為。
類反射方法
獲取Class對(duì)象
Object.getClass()
.class語(yǔ)法
原始類型不能使用Object.getClass()方法獲得Class對(duì)象
Class.forName()
如果可以得到類的全稱可以使用該方法獲取Class對(duì)象
基本類型的包裝類TYPE靜態(tài)變量
其他返回Class對(duì)象的方法
Class.getSuperclass()
Class.getClasses() ?返回作為類成員的所有公共類,接口和枚舉,包括繼承的成員。
Class.getDeclaredClasses() ?返回在此類中顯式聲明的所有類接口和枚舉。
Class.getDeclaringClass() ?返回在此類成員變量聲明的類,匿名類沒(méi)有DeclaringClass,但是有EnclosingClass
java.lang.reflect.Field.getDeclaringClass()
java.lang.reflect.Method.getDeclaringClass()
java.lang.reflect.Constructor.getDeclaringClass()
Class.getEnclosingClass() ?返回類的直接封閉類。
檢查類修飾符和類型
Class.getModifiers()方法獲取修飾符和類型 可以使用一個(gè)或多個(gè)影響其運(yùn)行時(shí)行為的修飾符聲明一個(gè)類:
public, protected, and private
abstract
static
final
strictfp
Annotations
獲取類的成員
獲取成員變量
Class?API列表返回值?繼承成員?私有成員?getDeclaredField()nonoyesgetField()noyesnogetDeclaredFields()yesnoyesgetFields()yesyesno
獲取成員方法
Class?API列表返回值?繼承方法?私有方法?getDeclaredMethod()nonoyesgetMethod()noyesnogetDeclaredMethods()yesnoyesgetMethods()yesyesno
構(gòu)造方法
Class?API列表返回值?繼承方法?私有方法?getDeclaredConstructor()noN/A1yesgetConstructor()noN/A1nogetDeclaredConstructors()yesN/A1yesgetConstructors()yesN/A1no
故障排除
警告報(bào)錯(cuò):Compiler Warning: "Note: ... uses unchecked or unsafe operations"
構(gòu)造函數(shù)不可訪問(wèn)時(shí)的InstantiationException
成員
Fields
獲取字段類型
Field.getType():獲取字段的類型
Field.getGenericType():獲取字段的泛型類型
檢索和解析字段修飾符
Field.getModifiers():獲取字段修飾符
Field.isSynthetic():判斷字段是否為合成的
Field.isEnumConstant():判斷字段是否為枚舉
獲取和設(shè)置字段值
Field.set*() :獲取字段值
Field.get*() :設(shè)置字段值
故障排除
IllegalArgumentException due to Inconvertible Types
NoSuchFieldException for Non-Public Fields
IllegalAccessException when Modifying Final Fields
Methods
獲取方法類型信息
Method.toGenericString()
Method.getReturnType()
Method.getGenericReturnType()
Method.getParameterTypes()
Method.getGenericParameterTypes()
Method.getExceptionTypes()
Method.getGenericExceptionTypes()
獲取方法參數(shù)的名字
Method.getParameters():獲取方法參數(shù)
Parameter.getType():獲取參數(shù)類型
Parameter.getName():獲取參數(shù)名稱
Parameter.Modifiers():獲取參數(shù)修飾符
Parameter.isImplicit():true如果在源代碼中隱式聲明此參數(shù)
Parameter.isNamePresent():true如果參數(shù)根據(jù).class文件具有名稱
Parameter.isSynthetic():true如果在源代碼中既未隱式聲明也未顯式聲明此參數(shù)
檢索和解析方法修飾符
Method.getModifiers():獲取方法修飾符
Method.isSynthetic():返回true此可執(zhí)行文件是否為合成構(gòu)造
Method.isVarArgs():返回true如果這個(gè)可執(zhí)行文件被宣布為帶有可變數(shù)量的參數(shù)
Method.isBridge():true如果此方法是橋接方法
調(diào)用方法
Method.invoke():調(diào)用方法
故障排除
NoSuchMethodException Due to Type Erasure
IllegalAccessException when Invoking a Method
IllegalArgumentException from Method.invoke()
InvocationTargetException when Invoked Method Fails
Constructors
獲取構(gòu)造函數(shù)
檢索和解析構(gòu)造函數(shù)修飾符
Constructor.getModifiers()
創(chuàng)建一個(gè)新實(shí)例
Constructor.newInstance():優(yōu)先使用
Class.newInstance()
故障排除
InstantiationException Due to Missing Zero-Argument Constructor
Class.newInstance() Throws Unexpected Exception
Problems Locating or Invoking the Correct Constructor
IllegalAccessException When Attempting to Invoke an Inaccessible Constructor
數(shù)組和枚舉類型
數(shù)組
識(shí)別數(shù)組類型
Class.isArray()
創(chuàng)建新數(shù)組
Array.newInstance()
獲取和設(shè)置數(shù)組及其組件
Array.set*()
Array.get()
故障排除
IllegalArgumentException due to Inconvertible Types
ArrayIndexOutOfBoundsException for Empty Arrays
IllegalArgumentException if Narrowing is Attempted
枚舉
識(shí)別枚舉類型
Class.isEnum():枚舉無(wú)法通過(guò)反射實(shí)例化,枚舉常量是唯一的
Class.getEnumConstants()
Field.isEnumConstant()
使用枚舉類型獲取和設(shè)置字段
Field.set()
Field.get()
故障排除
IllegalArgumentException When Attempting to Instantiate an Enum Type
IllegalArgumentException when Setting a Field with an Incompatible Enum Typc