Java中未经检查的分配警告

时间:2019-12-05 13:15:11

标签: java generics interface factory compiler-warnings

我正在使用一个API,并且要执行多个操作,目前正在开发中。为了隔离它,以便我可以轻松应对这些不断的更改,我使用方法Operation创建了一个功能接口perform,如下所示:

public interface Operation<R, T> {
    R perform(T arg);
}

我执行的所有操作都实现了此接口。例如,查找文件操作的实现如下:

public class Finder implements Operation<InputStream, String> {
    @Override
    public InputStream perform(String arg) {
        //Code to find the file
    }
}

此类使用InputStream作为返回值,并使用String作为参数,但是其他操作可以采用其他参数并具有不同的返回值...

为了能够创建任何操作,我创建了一个名为Enum的{​​{1}}来标识每个操作以及创建这些操作的工厂。工厂在下面:

OperationType

好的,这就是我的结构。这可能不是您的最佳选择,但这不是我要在此处解决的问题。问题是,当我尝试使用它时,会收到public class OperationsFactory { public static Operation create(OperationType type) { switch (type) { case FIND: return new Finder(); // cases for each operation default: throw new InvalidParameterException("Can't create operation type: " + type.toString()); } } } 警告,并且我希望删除该警告而无需添加注释以忽略此类警告(我认为这很糟糕)。让我放一个可能有此异常的方法的代码:

Unchecked Assignment

那么,Java专家,如何删除此警告?

2 个答案:

答案 0 :(得分:1)

这是因为您的OperationsFactory返回了Operation而不是正确归类的Operation<X, Y>,因此,如果将其分配给类型为findOperation的{​​{1}},则会得到此警告(因为编译器无法确保您分配正确的类型)。

遗憾的是,您无法将泛型添加到Operation<InputStream, String>(在将来的Java功能列表中),因此您将无法安全地做到这一点。消除警告的唯一方法是抑制警告。

请注意,您可以只使用enum而不是定义自己的功能接口。

答案 1 :(得分:1)

请注意此处没有类型参数:

public static Operation create(OperationType type) {
//                    ^ isn't something supposed to be there?

这称为raw type,与Operation<Object, Object>有效等效,但是,可以为任何Operation<A, B>A将其分配给B

促使您使用此警告的语言是指定返回操作的实际类型,例如:

public static Operation<InputStream, String> create(OperationType type) {

在现代代码中应避免使用原始类型,因为历史上的向后兼容原因,它们存在(Java在版本5之前没有泛型)。


编辑:实际上,想要要做的是需要相当高级的类型系统,并且对Java没有的依赖类型提供一些支持-如果您想避免警告的话, 那是。我建议您将选项枚举为纯字段,而不要尝试使用标准的enum,例如

public class OperationType {
  public static Operation<InputStream, String> FIND = ...
  public static Operation<OutputStream, String> WRITE = ...
  ...
}