从反射获得的相同Field是否始终是JAVA中的相同对象?

时间:2017-11-02 04:07:04

标签: java reflection

当调用this.getClass().getFields()以返回Field对象数组时,它会在后续调用中返回相同的对象吗?

如果有人想知道为什么会这样做,我试图将Field对象作为键,将其当前值作为值放在HashMap中以便稍后检索,同时可以对字段值进行更改,旧值为保持比较。

1 个答案:

答案 0 :(得分:1)

无法保证您将从不同的通话中获得相同的对象,并且您可能无法获胜。您可以做的一件事是检查Class类的源代码。

在我的jdk1.8.0_131安装中有以下作为getFields()的代码

public Field[] getFields() throws SecurityException {
    checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
    return copyFields(privateGetPublicFields(null));
}

现在你可以进一步了解,但我认为这会复制一些内部数据。

这并不意味着值不会作为HashMap中的键起作用,但是因为HashMap将使用.equals()和.hashCode()方法来确定两个键是否相同,而不是等于运算符' =='。

所以这里有一些笨重的代码来调查这个:

public static void main(String... none) throws Exception {
    Field[] fields1 = Point.class.getFields();
    Field[] fields2 = Point.class.getFields();
    for (int i = 0; i < fields1.length; ++i) {
        compare(fields1[i], fields2[i]);
    }
}

static void compare(Field field1, Field field2) {
    System.out.format("Field  %s\n", field1.getName());
    System.out.format("field1 == field2 -> %s\n", field1 == field2);
    System.out.format("field1.equals(field2) -> %s\n", field1.equals(field2));
    System.out.format("field1.hashCode() == field2.hashCode() -> %s\n", field1.hashCode() == field2.hashCode());
    System.out.println();
}

对我来说有输出:

Field  x
field1 == field2 -> false
field1.equals(field2) -> true
field1.hashCode()==field2.hashCode() -> true

Field  y
field1 == field2 -> false
field1.equals(field2) -> true
field1.hashCode() == field2.hashCode() -> true    

所以看起来你可以使用Field实例作为键。此外,如果您在Field上查看.equals()的文档,则会显示:

/**
 * Compares this {@code Field} against the specified object.  Returns
 * true if the objects are the same.  Two {@code Field} objects are the same if
 * they were declared by the same class and have the same name
 * and type.
 */ 

.hashCode()有类似的文档,因此您可以将该字段用作密钥。