java 使用反射比较字段值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13496026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing field values using reflection
提问by JonH
I am trying to compare the field values of two different objects in a generic way. I have a function (seen below) that takes in two Objects and then gets the fields and then compares the fields in a loop and adds the fields to a list if they are not the same - is this the proper way to do this?
我正在尝试以通用方式比较两个不同对象的字段值。我有一个函数(见下文),它接收两个对象,然后获取字段,然后在循环中比较字段,如果字段不相同,则将字段添加到列表中 - 这是执行此操作的正确方法吗?
public void compareFields(Object qa, Object qa4) throws FieldsNotEqualException
{
Field[] qaFields = qa.getClass().getFields();
Field[] qa4Fields = qa4.getClass().getFields();
for(Field f:qaFields)
{
for(Field f4:qa4Fields)
{
if(f4.equals(f))
{
found = true;
break;
}
else
{
continue;
}
}
}
if(!found)
{
report.add(/*some_formatted_string*/) //some global list
throw new FieldsNotEqualException();
}
}
I was googling and I saw that C# had like a PropertyInfo Class - does Java have anything like that?
ALSO, is there a way to do like f.getFieldValue()
-I know there is no method like this but maybe there is another way???
我在谷歌上搜索,我看到 C# 有一个 PropertyInfo 类——Java 有类似的东西吗?另外,有没有办法这样做f.getFieldValue()
- 我知道没有这样的方法,但也许还有另一种方法???
回答by tjg184
You might check out org.apache.commons.lang.builder.EqualsBuilder which will save you a lot of this hassle if you're wanting to do a field by field comparison.
如果您想逐个字段进行比较,您可以查看 org.apache.commons.lang.builder.EqualsBuilder,这将为您省去很多麻烦。
org.apache.commons.lang.builder.EqualsBuilder.reflectionEquals(Object, Object)
If you're wanting to compare fields yourself, check out java.lang.Class.getDeclaredFields()
which will give you all the fields including non-public fields.
如果您想自己比较字段,请查看java.lang.Class.getDeclaredFields()
这将为您提供所有字段,包括非公共字段。
To compare the value of the fields use f.get(qa).equals(f.get(qa4))
Currently, you are actually comparing the field instances and not the values.
要比较字段的值,请使用f.get(qa).equals(f.get(qa4))
Current,您实际上是在比较字段实例而不是值。
回答by Costi Ciudatu
Libraries like commons-beanutilscan help you if you want to compare bean properties (values returned by getters) instead of comparing field values.
如果您想比较 bean 属性(由 getter 返回的值)而不是比较字段值,像commons-beanutils这样的库可以帮助您。
However, if you want to stick with plain reflection, you should:
但是,如果您想坚持使用简单的反射,您应该:
- Use
Class.getDeclaredFields()
instead ofClass.getFields()
, as the latter only returns the public fields. - Since fields only depend on their class, you should cache the result and keep the fields in a static / instance variable rather than invoking
getDeclaredFields()
for each comparison. - Once you have an object of that class (say
o
), in order to get the value of some fieldf
for that particular object, you need to call:f.get(o)
.
- 使用
Class.getDeclaredFields()
代替Class.getFields()
,因为后者只返回公共字段。 - 由于字段仅依赖于它们的类,因此您应该缓存结果并将字段保存在静态/实例变量中,而不是
getDeclaredFields()
为每个比较调用。 - 一旦您拥有该类的对象(例如
o
),为了获取该f
特定对象的某个字段的值,您需要调用:f.get(o)
。
回答by Ahmed Ali
// If you want to have some fields, not all field then use this.
// 如果你想要一些字段,而不是所有字段,那么使用这个。
public boolean compareObject(Object object) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
{
String[] compareFields = { "fieldx", "fieldy","fieldz", "field15",
"field19"}; // list of all we need
for(String s : compareFields) {
Field field = DcrAttribute.class.getDeclaredField(s); // get a list of all fields for this class
field.setAccessible(true);
if(!field.get(this).equals(field.get(object))){ //if values are not equal
return true;
}
}
return false;
}