今天的主角: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