天天看點

JDK源碼/輪子分析 :反射包 java.lang.reflect③ 之 Field 擷取類的屬性字段資訊擷取Field 對象取字段值設定字段值其他

    今天的主角:java.lang.reflect.Field

    繼前面說的,一個類有它的抽象,構造方法有它的抽象,當然我們類中的字段也可以有它的抽象。 Field 也就是我們說的字段,類中的屬性。一般地我們在類中看到的樣子是這樣的: private String privateStr ; public static final  String publicStr ;          String protectStr ; public static final String finalStr = "110" ;     從上面可以看出,一個字段對象應該有5部份:字段的權限(private、public、protect),是否靜态是否不可變,字段的類型(String、Date等),字段名,字段值。

擷取Field 對象

    Class 對象中擷取Field 對象的方法有:      擷取所有權限的字段     Field    getDeclaredField(String name)     Field[]    getDeclaredFields()

擷取公共權限的字段     Field    getField(String name)     Field[]    getFields()

    首先貼上我們的測試pojo類 package com.hlmtest.java.reflect; public class TestFieldClass {       private String privateStr ;       public   String publicStr ;                 String protectStr ;       public static final String finalStr = "110" ;             public TestFieldClass(){}             public TestFieldClass(String privateStr ,String publicStr ,String protectStr ){             this . privateStr = privateStr ;             this . publicStr = publicStr ;             this . protectStr = protectStr ;                  }       public String getPrivateStr() {             return privateStr ;      }       public void setPrivateStr(String privateStr ) {             this . privateStr = privateStr ;      }       public String getPublicStr() {             return publicStr ;      }       public void setPublicStr(String publicStr ) {             this . publicStr = publicStr ;      }       public String getProtectStr() {             return protectStr ;      }       public void setProtectStr(String protectStr ) {             this . protectStr = protectStr ;      }       public String toString(){             return "privateStr:" + privateStr + ";publicStr:" + publicStr + ";protectStr:" + protectStr + ";finalStr:" + finalStr ;                }             }

package com.hlmtest.java.reflect; import java.lang.reflect.Field; public class TestFieldObject {       public static void main(String[] args ) {             getFieldInfo ();      }             public static void getFieldInfo(){             //先擷取Class 對象執行個體            Class<TestFieldClass> clzz = TestFieldClass. class ;            Field[] DeclFieldList =  clzz .getDeclaredFields();             for (Field field : DeclFieldList ){                 System. out .println( field .toString()+ ";" );            }            System. out .println( "<--我是華麗的分割線-->" );                        Field[] PublFieldList =  clzz .getFields();             for (Field field : PublFieldList ){                 System. out .println( field .toString()+ ";" );            }                  } }     運作結果為: private java.lang.String com.hlmtest.java.reflect.TestFieldClass.privateStr; public java.lang.String com.hlmtest.java.reflect.TestFieldClass.publicStr; java.lang.String com.hlmtest.java.reflect.TestFieldClass.protectStr; public static final java.lang.String com.hlmtest.java.reflect.TestFieldClass.finalStr; <--我是華麗的分割線--> public java.lang.String com.hlmtest.java.reflect.TestFieldClass.publicStr; public static final java.lang.String com.hlmtest.java.reflect.TestFieldClass.finalStr;

取字段值

    根據字段名取得字段 package com.hlmtest.java.reflect; import java.lang.reflect.Field; public class TestFieldObject {       public static void main(String[] args ) throws NoSuchFieldException, SecurityException {             getFieldInfo ();      }             public static void getFieldInfo() throws NoSuchFieldException, SecurityException{             //先擷取Class 對象執行個體            Class<TestFieldClass> clzz = TestFieldClass. class ;            Field field =  clzz .getDeclaredField( "publicStr" );            System. out .println( field .toString()+ ";" );                  }       }     

運作結果: public java.lang.String com.hlmtest.java.reflect.TestFieldClass.publicStr;

通過Field 對象擷取某執行個體的字段值: Object    get(Object obj) import java.lang.reflect.InvocationTargetException; public class TestFieldObject {       public static void main(String[] args ) throws NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {             getFieldInfo ();      }             public static void getFieldInfo() throws NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{             //先擷取Class 對象執行個體            Class<TestFieldClass> clzz = TestFieldClass. class ;                         //擷取有參的構造方法對象             @SuppressWarnings ( "rawtypes" )            Class[] paramstr = {String. class ,String. class ,String. class };            Constructor<TestFieldClass> instance = clzz .getConstructor( paramstr );             //調用Constructor 的newInstance(Object... initargs ) 方法獲得主對象執行個體            TestFieldClass obj = instance .newInstance( "我是私有屬性" , "我是公共屬性" , "我是預設屬性" );                        Field field =  clzz .getDeclaredField( "publicStr" );            Object valueObj = field .get( obj );            System. out .println( valueObj .toString()+ "" );                        Field[] fieldList =  clzz .getFields();             for (Field f : fieldList ){                 Object value = f .get( obj );                 System. out .println( f .toString()+ "-->" + value .toString()+ ";" );            }      } } 運作結果 我是公共屬性 public java.lang.String com.hlmtest.java.reflect.TestFieldClass.publicStr-->我是公共屬性; public static final java.lang.String com.hlmtest.java.reflect.TestFieldClass.finalStr-->110; 要注意的是,這個方法隻能擷取公共字段的值,私有字段的值是無法擷取 的,硬來要擷取則會報:java.lang.IllegalAccessException 并且會告訴你 你這個Class  can not access a member of 某類 with modifiers "private"。道理很簡單,私有的屬性本來就是供人家自己用的,你不可能在外面直接操作人家的。

設定字段值

可以擷取字段值自然就可以設定字段值,方法是:void    set(Object obj, Object value) package com.hlmtest.java.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; public class TestFieldObject {       public static void main(String[] args ) throws NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {             getFieldInfo ();      }             public static void getFieldInfo() throws NoSuchFieldException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{             //先擷取Class 對象執行個體            Class<TestFieldClass> clzz = TestFieldClass. class ;                         //擷取有參的構造方法對象             @SuppressWarnings ( "rawtypes" )            Class[] paramstr = {String. class ,String. class ,String. class };            Constructor<TestFieldClass> instance = clzz .getConstructor( paramstr );             //調用Constructor 的newInstance(Object... initargs ) 方法獲得主對象執行個體            TestFieldClass obj = instance .newInstance( "我是私有屬性" , "我是公共屬性" , "我是預設屬性" );                         //與取值一樣,私有的字段也是不可以直接設值的,是以此處隻取公共字段                Field[] fieldList =  clzz .getFields();             for (Field f : fieldList ){                  //final 修飾的字段是不可設值的,否則會報錯,這裡得排除                  if ( f .toString().indexOf( "final" )>-1){                       continue ;                 }                  f .set( obj , f .getName()+ "我給你設值了哈" );                 Object value = f .get( obj );                 System. out .println( f .toString()+ "-->" + value .toString()+ ";" );            }      } }     運作結果: public java.lang.String com.hlmtest.java.reflect.TestFieldClass.publicStr-->publicStr我給你設值了哈;

    到此也就差不多了,大家想要了解更多的使用方法的話當然還是文檔啦。

Field 的更多API可以查詢:      中文網址:http://tool.oschina.net/apidocs/apidoc?api=jdk-zh      英文網址:http://tool.oschina.net/apidocs/apidoc?api=jdk_7u4

其他

其他反射相關部落格:

    JDK源碼/輪子分析 :反射包 java.lang.reflect② 之 Constructor 擷取類的執行個體對象;

    JDK源碼/輪子分析 :反射包 java.lang.reflect ①之 Class 探秘;

    201800602