gpt4 book ai didi

java - 如何使用泛型类型访问静态内部类中的字段? (非常困难)

转载 作者:太空宇宙 更新时间:2023-11-04 09:23:28 29 4
gpt4 key购买 nike

我被这个问题困扰了近三个月,但自己无法解决。我希望这是可能的。我试图用我自己的自定义实体类注入(inject)此代码,该类很难访问,因为该类是静态的并且该字段是最终的。不知何故,我不确定泛型类型在访问它时是否存在问题。

public class EntityTypes<T extends Entity> {
private final EntityTypes.b<T> aZ;
[some code here]

public interface b<T extends Entity> {
T create(EntityTypes<T> entitytypes, World world);
}

public static class a<T extends Entity> {
private final EntityTypes.b<T> a;
[more code here]
}
}

到目前为止,我尝试使用反射,但我不断得到:

java.lang.IllegalArgumentException: Can not set net.server.EntityTypes$b field net.server.EntityTypes$a.a to net.server.EntityTypes

这是我的运行代码:

// works
ReflectionUtils.setFinal(EntityTypes.class, EntityTypes.VILLAGER, "aZ", (EntityTypes.b<CustomVillager>) CustomVillager::new);
// while this does not work!
ReflectionUtils.setFinal(EntityTypes.a.class, EntityTypes.VILLAGER, "a", (EntityTypes.b<CustomVillager>) CustomVillager::new);

public class ReflectionUtils {
// Does only work on Java 12 and above!!
public static void setFinal(Class cls, Object obj, String fieldName, Object value) {
try {
Field field = cls.getDeclaredField(fieldName);

FieldHelper.makeNonFinal(field);

field.setAccessible(true);
field.set(obj, value);
} catch (Exception e) {
e.printStackTrace();
}
}

// For Java 12 final field injection
// https://stackoverflow.com/questions/56039341/get-declared-fields-of-java-lang-reflect-fields-in-jdk12/
public final static class FieldHelper {
private static final VarHandle MODIFIERS;

static {
try {
var lookup = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup());
MODIFIERS = lookup.findVarHandle(Field.class, "modifiers", int.class);
} catch (IllegalAccessException | NoSuchFieldException ex) {
throw new RuntimeException(ex);
}
}

public static void makeNonFinal(Field field) {
int mods = field.getModifiers();
if (Modifier.isFinal(mods)) {
MODIFIERS.set(field, mods & ~Modifier.FINAL);
}
}
}
}

public class CustomVillager extends EntityVillager {

public CustomVillager(EntityTypes<? extends CustomVillager> entityTypes, World world) {
super(entityTypes, world);
}
}

最佳答案

您收到的异常意味着 Field 对象表示的类中的字段与您尝试设置它的对象的类不同。因此,在您的 setFinal() 方法中,您获得一个 Field 对象,表示类 cls 上名为 fieldName 的字段,然后尝试在对象 obj 上设置该字段。这意味着作为 obj 传入的对象必须是类 cls 的实例,否则它将无法工作。

查看调用setFinal()的两行,第一行获取EntityTypes类中的字段aZ;该字段仅存在于 EntityTypes 实例上。第二个 setFinal() 调用获取 EntityTypes.a 类中的字段 a;该字段仅存在于 EntityTypes.a 的实例上。您尝试在 EntityTypes.VILLAGER 上设置这两个字段。您尚未显示声明或初始化 EntityTypes.VILLAGER 的代码,因此我们不知道它是什么,但是只有当 EntityTypes.VILLAGER 既是 EntityTypes 的实例又是 EntityTypes.a 的实例时,这两行代码才会起作用,这是不可能的(因为它们都是类,都不是另一个的子类,并且 Java 没有类的双重继承)。所以这两行之一肯定是错误的。

关于java - 如何使用泛型类型访问静态内部类中的字段? (非常困难),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58035247/

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