我尝试使用反射打印类的整个层次结构。
为此,我定义了一个抽象超类A,它定义了toString(int offset)
方法:
abstract class A {
public String toString(int offset) {
StringBuilder builder = new StringBuilder();
try {
for (Field field : this.getClass().getDeclaredFields()) {
builder.append(String.join("", Collections.nCopies(offset, "\t")));
builder.append(field.getName()).append(": ");
field.setAccessible(true); // workaround
if (field.getType().isPrimitive()) {
// (int, float, ...)
builder.append(field.get(this));
} else if (field.getType().getName().contains("java.lang")) {
// (Integer, String, ...)
builder.append(field.get(this).toString());
} else {
// Other classes
builder.append("\n").append(A.class.cast(field.get(this)).toString(offset + 1));
}
builder.append("\n");
field.setAccessible(false); // workaround
}
} catch (Exception e) {
System.out.print(e);
}
return builder.toString();
}
}
然后我有一些类扩展了A类:
public class X extends A {
private String field1;
private Y field2;
}
public class Y extends A {
private String field3;
private String field4;
}
这些示例包含一些值。
调用x.toString(0)
的预期输出应该是:
field1: value1
field2:
field3: value3
field4: value4
如果不使用field.setAccessible(true)
,当我调用x.toString(0)
时,我得到IllegalAccessException: Class A can not access a member of class X with modifiers "private"
但我不明白为什么
当我在调试this
时检查引用时引用了X.class,那么为什么field.getValue(this)
不工作呢?this
不应该引用调用方法的类的示例吗?我错过什么了吗?
1条答案
按热度按时间ukqbszuj1#
private
并不意味着它对 instance 是私有的;这意味着它对 class 是私有的。继承不提供任何豁免(除了有限的protected
例外)。下面的示例在A
中编译失败,因为field2
不可访问:默认情况下,反射会施加相同的限制。