java - 如何防止使用 Java 泛型检查根类?

标签 java generics

这是我的问题。我有一个简单的测试代码。

public interface CommandFactory {
    public <T extends Command> T createCommand(Class<T> commandClass);
}
class Test implements CommandFactory {   
    public static void main(String[] args) {    
        Test test = new Test();
        test.createCommand(Command.class); // not valid case. should stop this action by compiler
    }    
    @Override
    public <T extends Command> T createCommand(Class<T> commandClass) {
        return commandClass.newInstance();
    }
}

如您所见,我传递了一个根类型 Command。但我想阻止这种情况。我想要的是传递给 createCommand 方法的只有 Command 的子项。

例如,正确的情况是传递扩展 CommandMyCommand 类。

Java 有可能吗?

附言

public abstract class AbstractCommand implements Command {
    // ...
}

AbstractCommand 类的解决方案不合适,因为我需要额外检查命令的类型。如果我不这样做,我将在传递 AbstractCommand.class 时得到 InstantiationException

最佳答案

您不能使用泛型强制执行此类限制。您可以做的最好的事情是在方法内部进行类型检查,如果接收到 Command.class 作为参数则抛出异常。甚至,为该场景添加文档注释:

/**
 * 
 * @param cl
 * @throws IllegalArgumentException
 *           when type of cl is Command.class
 * @return
 */
public <T extends Command> T createCommand(Class<T> cl) {
  if (cl == Command.class) {
    throw new IllegalArgumentException("Can only accept subclasses of Command");
  }
  return null;
}

更好的方法是向接口(interface)方法添加文档注释,以便任何实现类都知道该契约。

另一种方法,如果在您的情况下可行,可以在 CommandMyCommand 之间引入一个抽象类,并相应地更改边界:

class Command {
}

abstract class AbstractCommand extends Command {
}

class MyCommand extends AbstractCommand {
}

因此,您所有的子命令现在都将扩展 AbstractCommand 而不是 Command。然后,您的界面将如下所示:

public interface CommandFactory {
    public <T extends AbstractCommand> T createCommand(Class<T> cl);
}

然后,您不能将 Command.class 传递给它。但我认为这不会解决您要解决的具体问题(我们真的不知道它是什么),因为现在您可以将 AbstractCommand.class 传递给该方法。不过,您可以尝试使用 AbstractCommand 的可见性,因为您不会在其他地方使用它。

关于java - 如何防止使用 Java 泛型检查根类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29064985/

相关文章:

r - rep 真的是泛型吗?

Java Web 服务 - JDK 版本

Java 列表中不兼容的等式约束

java - Android - 动态设置绘图的渐变

java - 在 Android Studio 中运行 YouTube Activity 时出错

iOS Swift4 如何协调 T.Type 和类型(:) to pass dynamic class type as function parameter?

python - 使用可变泛型进行方法返回专门化

java - 如何将字符串转换为 Java 8 中的代码?

java - 多个通配符泛型方法的正确语法?

java - 为什么三元运算符不喜欢有界通配符的泛型类型?