0

In the following code I am returning a class that extends the type of Entity given the name of the class (it then corrects it so that Class.forName can find it properly).

How can I modify this so that I can still return a class that extends Entity without using @SuppressWarnings("unchecked")?

I tired a few variations using T and just ? but couldn't come up with an answer.

@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

4 回答 4

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;
    }
于 2014-01-15T22:13:09.040 回答
0

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

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

于 2014-01-15T22:11:16.533 回答
0

如果您可以在编译时访问该类,则可以直接返回,org.bukkit.entity.Egg.class而不是调用forName. 如果你不能,你就会被注释困住。

于 2014-01-15T22:11:33.673 回答
0

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

几点说明:而不是使用大量 if 块来确定实体孩子的名称,而是使用以下代码。

name = name.toLowerCase();
name = name.substring(0,1).toUpperCase() + name.substring(1);
于 2014-01-15T22:18:43.760 回答