Как получить доступ к полю внутри статического внутреннего класса с универсальным типом?(очень сложно) - PullRequest
1 голос
/ 21 сентября 2019

Я застрял в этой проблеме уже почти 3 месяца и не могу решить ее сам.Я надеюсь, что это возможно.Я пытаюсь внедрить этот код с моим собственным классом сущностей, к которому трудно получить доступ, потому что класс статичен, а поле является окончательным.Почему-то я не уверен, что универсальный тип является проблемой при доступе к нему.

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]
    }
}

До сих пор я пытался использовать Reflections, но я продолжаю получать:

java.lang.IllegalArgumentException: Невозможно установить net.server.EntityTypes $ b поле net.server.EntityTypes $ aa для 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
    // /8695740/poluchit-obyavlennye-polya-java-lang-reflect-fields-v-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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...