我正在使用一个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专家,如何删除此警告?
答案 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 = ...
...
}