Отражения Java. IDE говорит, что требует приведения к java.lang.Class, но когда это произойдет, выдается ClassCastException

Я недавно начал кодировать некоторые Размышления, и я сталкиваюсь с этой проблемой, когда я получаю класс. В основном название говорит само за себя: моя IDE (IntelliJ IDEA) говорит, что класс, который я создаю, выглядит так: Class myClass = aMethod.invoke(anObject); должен быть (очевидно) приведен к классу. Как только я это сделал и начал, он выдал ClassCastException, сказав, что фактический класс, который он получил через метод, не может быть приведен к java.lang.Class. Изменить: я пишу на Bukkit, чтобы сделать плагин для сервера Minecraft, и я пытаюсь получить доступ к NMS (Net Minecraft Server), более внутренний API, который основан на версии, но который можно получить для любого из них с помощью отражений (если только вы хочу сделать это единственно для одной версии). Вот еще немного кода:

static void setName(Player player, String name) {
        try {
            Method getHandle = player.getClass().getMethod("getHandle");
        Object entityPlayer = getHandle.invoke(player);
        Field bS = entityPlayer.getClass().getDeclaredField("bS");
        Object gameProfile = bS.get(entityPlayer);
        Field nameField = gameProfile.getClass().getDeclaredField("name");
        nameField.set(gameProfile, name);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            Main.getInstance().getLogger().log(Level.SEVERE, "Could not find method: ", e);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            Main.getInstance().getLogger().log(Level.SEVERE, "Could not find class: ", e);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            Main.getInstance().getLogger().log(Level.SEVERE, "Could not access reflection: ", e);
        } catch (InvocationTargetException e) {
            e.printStackTrace();
            Main.getInstance().getLogger().log(Level.SEVERE, "Could not invoke method: ", e);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            Main.getInstance().getLogger().log(Level.SEVERE, "Could not find field: ", e);
        }
    }

Теперь вы можете видеть, что я вызываю метод getHandle для объекта player, который, как я прямо указал, не основан на версии, хотя этот метод на самом деле принадлежит классу с именем CraftPlayer, который, хотя и не является частью nms, основан на версии тоже. Кроме того, вы можете увидеть некоторые попытки, которые вы можете найти бессмысленными в коде. Ошибка в основном это:

Caused by: java.lang.ClassCastException: net.minecraft.server.v1_11_R1.EntityPlayer cannot be cast to java.lang.Cl

Изменить: Сегодня я провел еще несколько тестов вокруг него и изменил многие части кода, на этот раз ошибка в том, что всякий раз, когда мой метод setName вызывается, NoSuchFieldException попадает в поле "bS", и я ПОЛНОСТЬЮ уверен, что он существует, По сути, это поле находится в другом классе с именем EntityHuman, но класс EntityPlayer расширяет его. Как я могу получить объект entityPlayer для приведения к EntityHuman? Во-первых, этот класс (EntityHuman) также является частью NMS, поэтому, поскольку он основан на версии, я буду использовать отражения, чтобы попытаться получить к нему доступ. Я могу получить к нему доступ через метод Class.forName, но я не знаю, что делать, даже с этим. Здесь ниже мой текущий код:

static void setName(Player player, String name) {
  try {
    Method getHandle = player.getClass().getMethod("getHandle");
    Object entityPlayer = getHandle.invoke(player);
    Field bS = entityPlayer.getClass().getDeclaredField("bS");
    Object gameProfile = bS.get(entityPlayer);
    Field nameField = gameProfile.getClass().getDeclaredField("name");
    nameField.set(gameProfile, name);
  } catch (NoSuchMethodException e) {
    e.printStackTrace();
    Main.getInstance().getLogger().log(Level.SEVERE, "Could not find method: ", e);
  } catch (IllegalAccessException e) {
    e.printStackTrace();
    Main.getInstance().getLogger().log(Level.SEVERE, "Could not access reflection: ", e);
  } catch (InvocationTargetException e) {
    e.printStackTrace();
    Main.getInstance().getLogger().log(Level.SEVERE, "Could not invoke method: ", e);
  } catch (NoSuchFieldException e) {
    e.printStackTrace();
    Main.getInstance().getLogger().log(Level.SEVERE, "Could not find field: ", e);
  }
}

1 ответ

Method.invoke(Object) возвращается Object, Вы должны привести его к тому типу, который возвращает отраженный метод. Если ваша IDE вводит вас в заблуждение, либо игнорируйте ее, либо отправьте отчет об ошибке в IDEA. Смотрите документы.

Другие вопросы по тегам