Отражения 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. Смотрите документы.