解析Java中的Field類和Method類。本站提示廣大學習愛好者:(解析Java中的Field類和Method類)文章只能為提供參考,不一定能成為您想要的結果。以下是解析Java中的Field類和Method類正文
Field類
Field類中界說了一些辦法,可以用來查詢字段的類型和設置或讀取字段的值。將這些辦法與繼續而來的member辦法聯合在一路.便可以使我們可以或許找出有關字段聲明的全體信息,而且可以或許把持某個特定對象或類的字段。
getGenericType辦法前往表現字段的聲明類型的Type實例。關於像String或int如許的平常類型,該辦法將前往與其相干聯的Class對象,例如String.class和int.classo關於像List < Stri ng>如許的參數化類型,該辦法將前往Parameterizedrype的實例,例如,對像T如許的類型,該辦法將前往Typevariable實例。
遺留上去的getType辦法將前往字段的類型的Class對象。關於平常類型,該辦法的行動與getGenericType辦法的雷同。假如字段的聲明類型是參數化類型,那末getType辦法將前往參數化類型的擦除所對應的Class對象,即原始類型的Class對象。例如,關於聲明為List < Stri ng>的對象,getType將前往Li St. class的。假如字段的聲明類型是類型變量,那末getType辦法將前往類型變量的擦除所對應的class對象。例如,假定有一個類FOO<丁>,關於其聲明為T類型的字段,get丁ype將前往object.
class對象。假如FOO被聲明為FOo<下extends Number >,那末get下ype將前往 Number.class.
我們可使用isEnumConstant辦法查詢一個字段能否是列舉常量,也能夠應用get和set辦法來獲得和設置字段的值。這些接收object引元並前往Obj ect值的辦法都有一種通用情勢,和一些可以直接處置根本類型的加倍特化的情勢。一切這些辦法都要接收一個引元,用來指定所要操作的對象。關於靜態字段,將疏忽這個對象引元,所以此時也能夠將其設
置為null。上面的辦法將打印一個對象的short型字段的值:
public static void printShortField(Object o, String name) throws NoSuchFieldException,IllegalAccessException { Field field=o.getClass().getField(name); short value=(Short) field.get(o); System.out.println(value);
get辦法的前往值可所以這個字段所援用的任何對象,假如該字段是根本類型,那末該辦法將前往適當類型的包裝器類對象。關於我們的”hort型字段,get辦法將前往包括該字段值的short類型的對象,而在將它賦值給當地變量value時,該對象值會主動停止拆箱轉換。
set辦法的應用也是相似的。將short型字段設置為所供給的值的辦法看起來能夠像上面如許:
public static voi setShortField(Object o,String name,short nv) throws NoSuchFieldException,IllegalAccessException Field field=0.getClass().getField(name); field .set(o .nv);
固然set接收的是Object類型的參數,然則我們可以直接傳遞一個short型的值,並用包裝轉換將其包裝為short類型的對象。
在下面的辦法中,假如指定對象的域是弗成拜訪的,而且這類拜訪權限掌握是強迫履行的,那末就會拋出IllegalACcessException異常;假如傳遞的對象與該域的類型分歧,就會拋出illegalArgumentException異常;假如該域長短靜態的且傳遞的對象援用是null,就會拋出NullPointerException異常;拜訪靜態域能夠會請求對類停止初始化,所以該辦法也會拋出ExceptionInInitializerError異常。
Field類還有特定的用來獲得和設置根本類型的辦法,例如,我們可以在Field對象上挪用getPrimitive7ype和set Primitive7ype,個中Primitive7ype是(首字母年夜寫的)根本類型名。get辦法可用於上面的語句:
short value=field.getshort(o);
而set辦法可用於上面的語句:
field.setshort(o, nv);
用以上兩種方法聲明的語句中可以免應用包裝器類對象。
Field類完成了AnnotatedElement接口,所以我們也能夠像16.2節那樣查詢運用於域
上的注解。
憑仗下面引見的辦法,我們可以將Field對象用作把持隨意率性值的一種方法,然則我們應當盡可能防止應用它。由於Java說話會在法式的編譯期盡量多地捕捉編程毛病,所以在我們編寫代碼時,應用的諸如「ield對象如許的直接辦法越少,那末在將它們編譯成代碼之前,便可以避免更多的毛病。並且,我們可以看到,在後面的代碼中,要想曉得究竟會產生甚麼,與在通俗的語法中直接應用域名的情形比擬,我們消費在浏覽代碼上的精神明顯年夜了很多。
Final字段
在平日情形下,對聲明為final的字段停止設置將會招致拋出IllegalACcessException
異常,這是我們所能預期的,由於final字段的值是永久不會轉變的。然則有些特別情形—例如在定制的反序列化(見20.8.4節)中,轉變final字段的值就是成心義的,我們只要在實例字段上能力經由過程反射完成這一點,而且條件是在該Field對象上曾經挪用過了setAccessible(true)。留意,可以勝利挪用setAccessible(true)是不敷的,必需確切挪用過它。
這類才能是為高度特化的高低文供給的,並不是用於通用目標,我們引見它僅僅是為了堅持內容的完全性。假如離開了特定的高低文,例如定制的反序列化,那末轉變final字段的值能夠會招致不測的乃至是災害性的效果。在這些高低文以外,不克不及包管對final字段的轉變是可見的。即使是在如許的高低文中,在應用這項技巧編碼時也必需包管平安機制不會障礙代碼的履行。轉變值為常質變量(見2.2.3節)的final字段將會招致此轉變弗成見,除非經由過程應用反射來完成這類修正。
Method類
method類和它從member類繼續而來的辦法使得我們可以取得辦法聲明的完全信息:
" public Type getGenericReturnTypeO:該辦法前往的是目的辦法的前往類型的Type對象。假如目的辦法被聲明為前往void,則該辦法前往void.classo
" public Type[] getGenericParameterTypes():該辦法前往目的辦法一切參數類型的Type對象數組,這些Type對象將依照參數的聲明次序存儲於在數組中。假如目的辦法沒有任何參數,則該辦法前往一個空數組。
.publ i c Type [] getGeneri caccepti onTypes Q:該辦法前往在throws子句中列出的一切異常類型的Type對象數組,這些Type對象將依照異常的聲明次序存儲在數組中。
假如目的辦法沒有聲明任何異常,則該辦法前往一個空數組。
Java還供給了getReturnType,getParameterTypes和getExceptionTypes辦法,用來前往Cl as”對象而不是Type對象。就像在應用Field.getType時,參數化類型和類型變量是由它們的擦除所對應的Class對象表現的。
method類完成了AnnotatedElement,而且我們可以像16.2節所評論辯論的那樣去查詢運用於辦法上的注解。別的,Method類還供給了getParameterAnnotations,用來供給對運用於辦法參數上的注解停止拜訪。getParameterAnnotations辦法可以前往Annotation數組,個中最外層數組的每個元素都與辦法的參數絕對應;假如某個參數沒有任何注解,則該辦法為這個參數前往一個長度為0的Annotation數組。假如method對象所表現的辦法本身就是一個注解元素,那末getDefaultvalue辦法將前往一個表現該元素默許值的Object對象;假如method對象自己不是注解元素或許它沒有默許值,則該辦法將前往null.Method類也完成了GenericDeclaration,是以界說了getTypeParameters辦法,該辦法將前往一個Typevariable對象數組。假如給定的method對象表現的不是泛型辦法,該辦法將前往一個空數組。
我們可使用isvarArgs辦法來檢討某個method對象能否是一個可變引元辦法,而i sBridge辦法可以用來檢討它能否是一個橋接辦法
Method對象最風趣的用法就是反射地挪用它本身:
.public object invoke(object onThis,object…args)throws IllegalACcessException,IllegalArgumentException,工nvocation下argetException:該辦法在onThis對象上挪用method對象界說的辦法,並用args的值來設置被挪用辦法的參數。關於非靜態辦法,onThis的現實類型就肯定了將要挪用辦法的哪一種完成,而關於靜態辦法,onThis會被疏忽,而且平日會設置為null. args值的數目必需和被挪用辦法的現實參數數目雷同,而且這些值的類型必需全體都可賦值給那些被挪用辦法的參數;不然,我們將會獲得工llegalArgumentException異常。請留意,可變引元辦法的最初一個參數是一個數組,所以我們必需用現實想要傳遞的“可變”引元來填充該數組。假如我們想挪用我們沒有拜訪權限的辦法,該辦法就會拋出IllegalACcessException異常。假如被挪用辦法不是on下his對象的辦法,該辦法會拋收工llegalArgumentExcepti on異常。假如onThis為null而且長短靜態的,該辦法就會拋出NO 1PointerException異常。假如這個 method對象表現的是靜態辦法,而且聲明這個靜態辦法的類仍處於待初始化狀況,該辦法就會拋出ExceptionIn工nitializerError異常。假如被挪用法出異冪,談萬法就會拋出InvocationTargetException異常。
當我們應用invoke辦法時,可以直接傳遞根本類型,也能夠應用適合的包裝器類。包裝器類表現的類型必需可賦值給辦法所聲明的參數類型。我們可使用Long,Float或Double來包裝double類型的引元,然則不克不及用Double來包裝long或float類型的引元,由於double不是可賦值給long或們oat的。對invoke辦法前往的object的處置辦法和Field.get一樣,都是前往對應於它們的包裝器類的根本類型。假如辦法聲明為void, invoke辦法將前往null,
簡略地說,就是我們在用invoke來挪用辦法時,只能應用在Java說話中正當的與其參數
具有雷同類型和值的引元。例如,上面的挪用
return str.indexof(".”,8);
可以用反射寫成以下情勢:
Throwable fa們ure; try{ Method indexM=String.class. getMethod("index0f",String.class,int.class); return (Integer) indexM.invoke(str,”,”,8); }catch (NoSuchMethodException e){ failure=e; }catch (InvocationTargetException e){ fa們ure=e .getCause(); }catch (IllegalAccessException e){ failure=e; } throw fa們ure;
固然編譯器關於直接挪用所做的平安性檢討,在應用反射的情形下,只能在運轉時應用invoke時停止,然則基於反射的代碼確切具有與直接挪用的代碼在語義上等效的平安性檢討。拜訪權限檢討能夠會以略為分歧的方法履行—平安治理器能夠會謝絕拜訪我們的包中的某個辦法,即便我們可以直接挪用該辦法。
當我們可使用這類情勢的挪用時,我們有充足的來由去防止它。然則假如我們在編寫調試器或其他須要將用戶輸出說明為對對象操作的泛型運用時應用invoke或get/set辦法,就會顯得很公道。method對象在某種水平上可以看成相似其他說話中的辦法指針來應用,然則我們有更好的對象,特別是接口、籠統類和嵌套類,可以用來處置那些平日在其他說話頂用辦法指針處理的成績。