当调用 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/