dsl*_*ake 0 java reflection minecraft
我查看了我能找到的与Java反射相关的每个条目,似乎没有人能解决我正在处理的情况.我有一个带有静态嵌套类的类A,B类A还有一个字段,一个类型为B的数组,称为bArray.我需要从类外部访问此字段以及bArray元素的私有成员.我已经能够使用getDeclaredClasses获取静态嵌套类,我通常会使用getDeclaredFields和setAccessible获取私有字段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
}
}
Run Code Online (Sandbox Code Playgroud)
我最终需要从A类外部获取bArray及其字段theX和Y.
我不能使用像Class.forName("classname")这样的类的名称,因为代码都是通过混淆器运行的,并且名称都会发生变化,当然除了字符串中的名称.由于混淆,我可以使用字段顺序(索引)而不是名称.除了这个私有的静态嵌套数组字段之外,我已经设法找出了我需要的所有字段,方法和其他东西.
这是我尝试过的方向.这前三行似乎做了我想要的,但第四行说ABArray无法解决:
A myA = new A();
Class AB = stealNamedInnerClass(A.class);
Class ABArray = Array.newInstance(AB, 0).getClass();
ABArray myABArray = (ABArray)stealAndGetField(myA, ABArray);
Run Code Online (Sandbox Code Playgroud)
这些是我引用的实用程序函数:
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;
}
Run Code Online (Sandbox Code Playgroud)
是的,您可以简单地遍历您的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) + "]");
}
Run Code Online (Sandbox Code Playgroud)
在测试时,请确保您的数组已完全初始化(即包含非空值).
| 归档时间: |
|
| 查看次数: |
1200 次 |
| 最近记录: |