java - JAVA中同一个Field通过反射得到的总是同一个对象吗?

标签 java reflection

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

如果有人想知道为什么会问这个问题,我尝试将 Field 对象作为键,将它们的当前值作为 HashMap 中的值,以便稍后检索,同时可以对字段值进行更改,旧值是保留用于比较。

最佳答案

无法保证您会从不同的调用中获得相同的对象,而且很可能不会。您可以做的一件事是检查 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() 方法来确定两个键是否相同,而不是 equals 运算符'=='。

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

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() 有类似的文档,因此您可能可以使用该字段作为键。

关于java - JAVA中同一个Field通过反射得到的总是同一个对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47067449/

相关文章:

java - 如何检查整数是否在给定范围内?

java - 如何序列化 android.location 类?

java - 使用抽象类中的重写方法 (Java)

java - 如何找到某个接口(interface)的所有实现?

java - 反射 - Method::get Generic Return Type no generic - 可见性

c# - 如何在 C# 中从字符串创建实例?

java - 如何使用 Joda-Time 在 Java 中设置时间属性

java - 使用 Jackson 将 JSON 字符串或对象反序列化为 String 字段

java - 通过 Intellij IDEA 运行 Hadoop MR 作业

xml - Ruby:attr_accessor 生成的方法 - 如何迭代它们(以 to_s - 自定义格式)?