Java: возвращение расширенного класса по имени
В следующем коде я возвращаю класс, который расширяет тип Entity по имени класса (затем он исправляет его так, чтобы Class.forName
могу найти это правильно).
Как я могу изменить это так, чтобы я все еще мог возвращать класс, который расширяет Entity без использования @SuppressWarnings("unchecked")
?
Я устал несколько вариантов, используя T
и просто ?
но не смог придумать ответ.
@SuppressWarnings("unchecked")
public static Class<? extends Entity> getProjectile(String name) {
if (name.equalsIgnoreCase("ARROW"))
name = "Arrow";
else if (name.equalsIgnoreCase("ENDERPEARL"))
name = "EnderPearl";
else if (name.equalsIgnoreCase("EXPERIENCEORB"))
name = "ExperienceOrb";
else if (name.equalsIgnoreCase("FIREBALL"))
name = "Fireball";
else if (name.equalsIgnoreCase("FIREWORK"))
name = "Firework";
else if (name.equalsIgnoreCase("SMALLFIREBALL"))
name = "SmallFireball";
else if (name.equalsIgnoreCase("SNOWBALL"))
name = "Snowball";
else
name = "Egg";
try {
return (Class<? extends Entity>) Class.forName("org.bukkit.entity." + name);
} catch (ClassNotFoundException e) {
return Egg.class;
}
}
4 ответа
Ответ на ваш вопрос: Class.forname
не очень "безопасный" код, поэтому вы получите сообщения компиляции. Я бы сказал, придерживайтесь того, что у вас есть, как это работает.
Несколько замечаний: вместо этого массивного блока if для определения имени дочернего объекта, используйте вместо этого следующий код.
name = name.toLowerCase();
name = name.substring(0,1).toUpperCase() + name.substring(1);
Ты не можешь Class.forName(String)
объявлен как возвращающий ссылку типа Class<?>
который вы затем должны разыграть, если хотите, чтобы он соответствовал Class<? extends Entity>
Это приведение небезопасно, поэтому компилятор предупреждает вас.
Альтернативой является фактическое Class
объекты в if-else
блок вместо имен.
Если вы можете получить доступ к классу во время компиляции, вы можете просто вернуться, скажем, org.bukkit.entity.Egg.class
вместо звонка forName
, Если вы не можете, вы застряли с аннотацией.
Компилятор не может угадать, расширяется ли класс Entity
просто глядя на возможные значения для Class.forName(...)
вызов.
Вы можете использовать Class aClass
переменная вместо String name
для хранения ответа, чтобы избежать предупреждения:
public static Class<? extends Entity> getProjectile(String name) {
Class<? extends Entity> ans;
if (name.equalsIgnoreCase("ARROW"))
ans = Arrow.class;
else if (name.equalsIgnoreCase("ENDERPEARL"))
ans = EnderPearl.class;
else if (name.equalsIgnoreCase("EXPERIENCEORB"))
ans = ExperienceOrb.class;
else if (name.equalsIgnoreCase("FIREBALL"))
ans = Fireball.class;
else if (name.equalsIgnoreCase("FIREWORK"))
ans = Firework.class;
else if (name.equalsIgnoreCase("SMALLFIREBALL"))
ans = SmallFireball.class;
else if (name.equalsIgnoreCase("SNOWBALL"))
ans = Snowball.class;
else
ans = Egg.class;
return ans;
}