gpt4 book ai didi

java - 使用Java反射,我可以访问私有(private)静态嵌套类类型的私有(private)字段吗?

转载 作者:行者123 更新时间:2023-12-01 07:07:22 33 4
gpt4 key购买 nike

我浏览了我能找到的与 Java 反射相关的所有条目,但似乎没有一个条目能够解决我正在处理的情况。我有一个类 A,其中有一个静态嵌套类 B。类 A 还具有一个 B 类型的数组作为其字段之一,称为 bArray。我需要从类外部以及 bArray 元素的私有(private)成员访问该字段。我已经能够使用 getDeclaredClasses 获取静态嵌套类,并且通常会使用 getDeclaredFields 和 setAccessible 获取私有(private)字段 bArray,但我似乎无法将它们全部放在一起以便能够从类外部迭代 bArray。

这是我正在使用的示例类结构。

public class A {
private A.B[] bArray = new A.B[16];

private static class B {
private int theX;
private int theY;

B(int x, int y) {
this.theX = x;
this.theY = y;
}
// More methods of A.B not included
}
}

我最终需要从 A 类外部获取 bArray 及其字段 theX 和 theY。

我不能使用像 Class.forName("classname") 这样的类的名称,因为所有代码都是通过混淆器运行的,并且除了字符串中的名称之外,名称都发生了变化。我可以使用字段顺序(索引),但由于混淆而不能使用名称。我已经成功地选出了除了这个私有(private)静态嵌套数组字段之外的所有字段、方法和我需要的东西。

这是我尝试过的方向。前 3 行似乎做了我想要的,但第四行说 ABArray 无法解析:

A myA = new A();
Class AB = stealNamedInnerClass(A.class);
Class ABArray = Array.newInstance(AB, 0).getClass();
ABArray myABArray = (ABArray)stealAndGetField(myA, ABArray);

这些是我引用的实用函数:

public static Field stealField(Class typeOfClass, Class typeOfField)
{
Field[] fields = typeOfClass.getDeclaredFields();
for (Field f : fields) {
if (f.getType().equals(typeOfField)) {
try {
f.setAccessible(true);
return f;
} catch (Exception e) {
break; // Throw the Exception
}
}
}
throw new RuntimeException("Couldn't steal Field of type \"" + typeOfField + "\" from class \"" + typeOfClass + "\" !");
}

public static Object stealAndGetField(Object object, Class typeOfField)
{
Class typeOfObject;

if (object instanceof Class) { // User asked for static field:
typeOfObject = (Class)object;
object = null;
} else {
typeOfObject = object.getClass();
}

try {
Field f = stealField(typeOfObject, typeOfField);
return f.get(object);
} catch (Exception e) {
throw new RuntimeException("Couldn't get Field of type \"" + typeOfField + "\" from object \"" + object + "\" !");
}
}

public static Class stealNamedInnerClass(Class clazz)
{
Class innerClazz = null;
Class[] innerClazzes = clazz.getDeclaredClasses();
if (innerClazzes != null) {
for (Class inner : innerClazzes) {
if (!inner.isAnonymousClass())
return inner;
}
}
return null;
}

最佳答案

是的,您可以简单地迭代 bArray:

// First, get bArray
Class<A> aClass = A.class;
A instance = new A();
Class<?> bClass = aClass.getDeclaredClasses()[0];
Field field = aClass.getDeclaredField("bArray");
field.setAccessible(true);
Object[] bArray = (Object[]) field.get(instance);

// Then iterate and get field value
Field xField = bClass.getDeclaredField("theX");
xField.setAccessible(true);
Field yField = bClass.getDeclaredField("theY");
yField.setAccessible(true);
for (int i = 0; i < bArray.length; ++i) {
Object bInstance = bArray[i];
System.out.println("Item " + i + ": [x = " + xField.get(bInstance) + ", y = " + yField.get(bInstance) + "]");
}

当您测试它时,请确保您的数组已完全初始化(即包含非空值)。

关于java - 使用Java反射,我可以访问私有(private)静态嵌套类类型的私有(private)字段吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21132865/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com