Java 如何使用泛型类型访问静态内部类中的字段?(非常困难)
我被这个问题困扰了将近3个月,自己也解决不了。我希望这是可能的。我试图用我自己的自定义实体类来注入这段代码,这很难访问,因为该类是静态的,字段是最终的。不知何故,我不确定泛型类型在访问它时是否有问题Java 如何使用泛型类型访问静态内部类中的字段?(非常困难),java,generics,reflection,Java,Generics,Reflection,我被这个问题困扰了将近3个月,自己也解决不了。我希望这是可能的。我试图用我自己的自定义实体类来注入这段代码,这很难访问,因为该类是静态的,字段是最终的。不知何故,我不确定泛型类型在访问它时是否有问题 公共类EntityTypes{ 私有最终实体类型。b aZ; [这里有一些代码] 公共接口b{ T创建(EntityTypes EntityTypes,World World); } 公共静态a类{ 私有最终实体类型b a; [此处有更多代码] } } 到目前为止,我尝试使用反射,但我一直得到:
公共类EntityTypes{
私有最终实体类型。b aZ;
[这里有一些代码]
公共接口b{
T创建(EntityTypes EntityTypes,World World);
}
公共静态a类{
私有最终实体类型b a;
[此处有更多代码]
}
}
到目前为止,我尝试使用反射,但我一直得到:
java.lang.IllegalArgumentException:无法将net.server.EntityTypes$b字段net.server.EntityTypes$a.a设置为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);
}
}
//有效
ReflectionUtils.setFinal(EntityTypes.class,EntityTypes.VILLAGER,“aZ”,(EntityTypes.b)CustomVillager::new);
//虽然这不起作用!
ReflectionUtils.setFinal(EntityTypes.a.class,EntityTypes.VILLAGER,“a”,(EntityTypes.b)CustomVillager::new);
公共类反射单元{
//仅适用于Java12及以上版本!!
公共静态void setFinal(类cls、对象obj、字符串字段名、对象值){
试一试{
Field Field=cls.getDeclaredField(fieldName);
FieldHelper.makeNonFinal(字段);
字段。setAccessible(true);
字段设置(对象,值);
}捕获(例外e){
e、 printStackTrace();
}
}
//用于Java12最终字段注入
// https://stackoverflow.com/questions/56039341/get-declared-fields-of-java-lang-reflect-fields-in-jdk12/
公共最终静态类FieldHelper{
私有静态最终VarHandle修饰符;
静止的{
试一试{
var lookup=MethodHandles.privateLookupIn(Field.class,MethodHandles.lookup());
修饰符=lookup.findVarHandle(Field.class,“修饰符”,int.class);
}捕获(IllegalAccessException | NoSuchFieldException ex){
抛出新的运行时异常(ex);
}
}
公共静态无效makeNonFinal(字段){
int mods=field.getModifiers();
if(修饰符isFinal(mods)){
MODIFIERS.set(字段,mods&~Modifier.FINAL);
}
}
}
}
公共类CustomVillager扩展实体Villager{
public CustomVillager(EntityTypes您得到的异常意味着字段
对象表示类上的字段,该字段和您试图设置它的对象的类不同。所以在您的setFinal()中
方法,在类cls
上获得一个表示名为fieldName
的字段的Field
对象,然后尝试在对象obj
上设置该字段。这意味着作为obj
传入的对象必须是类cls
的实例,否则它将无法工作
查看调用setFinal()
的两行,第一行在EntityTypes
类中获取字段aZ
;该字段仅存在于EntityTypes
的实例上。第二行setFinal()
call获取EntityTypes.a
类中的a
字段;该字段仅存在于EntityTypes.a
的实例中。您尝试将这两个字段都设置为EntityTypes.VILLAGER
。您尚未显示声明或初始化EntityTypes.VILLAGER的代码,因此我们不知道它是什么,b但是只有当EntityTypes.VILLAGER
既是EntityTypes
的一个实例,又是EntityTypes.a的一个实例时,这两行才起作用,这是不可能的(因为它们都是类,都不是另一个的子类,Java没有类的双重继承)所以这两行中的一行肯定是错误的。您得到的异常意味着字段
对象表示类上的字段,该字段和您试图设置它的对象的类不同。所以在setFinal()中
方法,在类cls
上获得一个表示名为fieldName
的字段的Field
对象,然后尝试在对象obj
上设置该字段。这意味着作为obj
传入的对象必须是类cls
的实例,否则它将无法工作
查看调用setFinal()
的两行,第一行在EntityTypes
类中获取字段aZ
;该字段仅存在于EntityTypes
的实例上。第二行setFinal()
call获取EntityTypes.a
类中的a
字段;该字段仅存在于EntityTypes.a
的实例中。您尝试将这两个字段都设置为EntityTypes.VILLAGER
。您尚未显示声明或初始化EntityTypes.VILLAGER的代码,因此我们不知道它是什么,b但是只有当EntityTypes.VILLAGER
既是EntityTypes
的一个实例,又是EntityTypes.a的一个实例时,这两行才起作用,这是不可能的(因为它们都是类,都不是另一个的子类,Java没有类的双重继承)。因此,这两行中的一行肯定是错误的。如果您发布演示此问题的工作代码,您将更有可能得到快速响应。我看了一点,但对我来说,我认为我需要编写一个示例,如果我这样做,它甚至可能与您的问题不匹配。谢谢。我刚刚还添加了ReflectionUtils类。这是m吗inecraft?可能是bukkit one?请提供您正在更改的确切内容,以便更容易测试。它是否需要在中工作