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
的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
警告,并且我希望删除该警告而无需添加注释以忽略此类警告(我认为这很糟糕)。让我放一个可能有此异常的方法的代码:
public InputStream performFindOperation(String path) { Operation<InputStream, String> findOperation = OperationsFactory.create(OperationType.FIND); //warning here!! return findOperation.perform(path); }
因此,Java专家,如何删除此警告?
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之前没有泛型)。EDIT:实际上,want要做的事情需要相当高级的类型系统,并且对Java没有的依赖类型提供某些支持-如果要避免警告,那就是。我建议您将选项枚举为纯字段,而不要尝试使用标准的
enum
,例如public class OperationType { public static Operation<InputStream, String> FIND = ... public static Operation<OutputStream, String> WRITE = ... ... }
OperationsFactory
返回了Operation
而不是正确归类的Operation<X, Y>
,因此,如果将其分配给类型为findOperation
的Operation<InputStream, String>
,则会收到此警告(因为编译器无法保证您可以分配正确的类型)。可悲的是,您无法将泛型添加到enum
(在将来的Java功能列表中),因此您将无法安全地做到这一点。摆脱警告的唯一方法是抑制它。
作为旁注,您可以只使用java.util.Function<T, R>
而不是定义自己的功能接口。