【问题标题】:Java: Returning an extended class given it's nameJava:返回一个给定名称的扩展类
【发布时间】:2014-01-15 22:08:16
【问题描述】:

在下面的代码中,我返回一个类,该类扩展了给定类名称的实体类型(然后它会更正它,以便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;
    }
}

【问题讨论】:

  • 与您的问题无关,但要清理该代码,将大写字符串变成一个枚举并摆脱 if - 在开头放置一个静态块并启动一个静态 Map 检查 enum 的 equals 方法中的相等性并实现 hashcode

标签: java generics casting extends unchecked-cast


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        编译器无法仅通过查看Class.forName(...) 调用的可能值来猜测类是否扩展Entity

        您可以使用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;
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-10
          • 2021-05-02
          • 1970-01-01
          • 1970-01-01
          • 2013-02-14
          • 1970-01-01
          相关资源
          最近更新 更多