Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用泛型类型访问静态内部类中的字段?(非常困难)_Java_Generics_Reflection - Fatal编程技术网

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

Java 如何使用泛型类型访问静态内部类中的字段?(非常困难),java,generics,reflection,Java,Generics,Reflection,我被这个问题困扰了将近3个月,自己也解决不了。我希望这是可能的。我试图用我自己的自定义实体类来注入这段代码,这很难访问,因为该类是静态的,字段是最终的。不知何故,我不确定泛型类型在访问它时是否有问题 公共类EntityTypes{ 私有最终实体类型。b aZ; [这里有一些代码] 公共接口b{ T创建(EntityTypes EntityTypes,World World); } 公共静态a类{ 私有最终实体类型b a; [此处有更多代码] } } 到目前为止,我尝试使用反射,但我一直得到:

我被这个问题困扰了将近3个月,自己也解决不了。我希望这是可能的。我试图用我自己的自定义实体类来注入这段代码,这很难访问,因为该类是静态的,字段是最终的。不知何故,我不确定泛型类型在访问它时是否有问题

公共类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?请提供您正在更改的确切内容,以便更容易测试。它是否需要在中工作