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;
    }
Другие вопросы по тегам