今天的主角: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可以查询:
其他
其他反射相关博客:
JDK源码/*分析 :反射包 java.lang.reflect② 之 Constructor 获取类的实例对象;
JDK源码/*分析 :反射包 java.lang.reflect ①之 Class 探秘;
201800602