Java:根据它的名称返回扩展类

时间:2014-01-15 22:08:17

标签: java generics casting extends unchecked-cast

在下面的代码中,我返回一个类,该类扩展了给定类名的Entity类型(然后对其进行更正,以便Class.forName可以正确找到它。)

如何修改此设置,以便我仍然可以返回一个扩展实体而不使用 @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 个答案:

答案 0 :(得分:0)

你做不到。 Class.forName(String)被声明为返回类型为Class<?>的引用,如果您希望它符合Class<? extends Entity>,则必须进行转换。此转换是不安全的,因此编译器会向您发出警告。

另一种方法是在Class块中使用实际的if-else对象而不是名称。

答案 1 :(得分:0)

如果您可以在编译时访问该类,则可以返回,例如org.bukkit.entity.Egg.class而不是调用forName。如果你不能坚持使用注释。

答案 2 :(得分:0)

编译器只能通过查看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;
    }

答案 3 :(得分:0)

回答您的问题:Class.forname不是非常“安全”的代码,因此您将获得编译消息。我会说坚持你所拥有的,因为它有效。

一些评论:而不是用于确定实体子名称的大块if块,而是使用以下代码。

name = name.toLowerCase();
name = name.substring(0,1).toUpperCase() + name.substring(1);