我正在为我的论文做一个项目,无法解决以下问题......
在某些情况下,我有几种实现接口并扩展抽象类(实现接口部分)的方法。
MFModel
是一个包装类,它封装了我的数据模型和数据流上某些操作所需的几个函数。
class MFModel<D extends IDataModel<?, ?>> {
public MFModel() {}
public MFModel(final D dataModel, final IPredictor<D> predictor, final ILearner learner) {}
}
RecDataModel
是我的数据模型实现之一。
class RecDataModel implements IDataModel<Map<Long, Map<Long, Double>>, IDataStats> {}
BaselinePredictor
是为我的模型数据提供操作的功能之一,同样适用于NullLearner
。
class BaselinePredictor
extends AbstractModularFunction<IPredictor<IDataModel<?, IDataStats>>>
implements IPredictor<IDataModel<?, IDataStats>> {}
class NullLearner implements ILearner {}
AbstractModularFunction<T>
是一个抽象的部分实现接口。
abstract class AbstractModularFunction<T> implements IModularFunction<T> {}
以下接口定义了我的模型的数据内容,并为我的函数提供了可用的功能:
interface IDataModel<T, S> {}
interface IDataStats {}
interface IPredictor<D> extends IModularFunction<IPredictor<D>> {}
interface ILearner extends IModularFunction<ILearner> {}
interface IModularFunction<T> {}
在尝试实例化新的MFModel
时,我遇到了以下问题:首先,如果我实例化ILearner
和IPredictor<?>
的已实现版本,我就不会警告或错误:
MFModel<?> okayModel = new MFModel<>(new RecDataModel(), new BaselinePredictor(), new NullLearner());
但是,如果我尝试使用这些接口,Eclipse会抛出cannot infer type arguments for MFModel<>
错误:
ILearner learnerFunc = new NullLearner();
IPredictor<?> predictorFunc = new BaselinePredictor();
MFModel<?> problemModel = new MFModel<>(new RecDataModel(), predictorFunc, learnerFunc);
无法推断MFModel&lt;&gt;
的类型参数
如果省略菱形运算符,我可以编译并运行我的代码,然后反过来给我原始类型警告:
MFModel<?> warnModel = new MFModel(new RecDataModel(), predictorFunc, learnerFunc);
类型安全:构造函数MFModel(IDataModel,IPredictor,ILearner)属于原始类型MFModel。应该是泛型类型MFModel的引用 参数
由于我不喜欢抑制警告(或稍后接受可能的错误),我想知道类型参数错误源自何处。
这是一个显示我的问题的可运行代码段:http://ideone.com/K5BaIN
我很感激您可以给我的任何意见,因为我必须承认这些嵌套的仿制药对我来说很难掌握。它们降低了所需的强制转换和包装代码的数量,这就是为什么我要保留它们。此外,在某些情况下,由于模块化代码部分可以并且应该可以轻松地交换不同的实现,我无法确定我将获得哪种对象。
答案 0 :(得分:1)
出于兼容性原因允许使用它们,但是使用它们会首先破坏使用泛型的目的,因为它们违反了使用泛型所实现的几乎所有安全性和抽象性。
Wildcard表示对类型变量的存在量化,因此它们具有特殊用途。不应该使用它们来避免必须编写(并考虑)具体类型。如果您不想编写类型,您可以使用动态类型更多的语言。
考虑更换
IPredictor<?> predictorFunc = new BaselinePredictor();
使用以下两种陈述之一。
BaselinePredictor predictorFunc = new BaselinePredictor();
IPredictor<IDataModel<?, IDataStats>> predictorFunc = new BaselinePredictor();
即使
MFModel<?> okayModel = ...
当您尝试使用okayModel
时,会产生问题。
编译器使用其他表达式的类型推断某些表达式的类型。如果你拒绝提供具体类型的任何东西,那么类型推断将变得不可能。
在以下代码中,
ILearner learnerFunc = new NullLearner();
IPredictor<?> predictorFunc = new BaselinePredictor();
MFModel<?> problemModel = new MFModel<>(new RecDataModel(), predictorFunc, learnerFunc);
predictorFunc
变量的编译器具体类型参数。MFModel
构造函数提供编译器具体类型参数。problemModel
变量的编译器具体类型参数。因此,以下错误是合理的。
无法推断MFModel&lt;&gt;
的类型参数
希望这有帮助。
祝你好运。