jur*_*rym 8 java inference type-inference
第一次发帖,对不起,标题可能是垃圾。我正在尝试使用类型推断,但是在使用工厂模式时却努力使其正常工作,让我扔掉一些代码以使其更加清晰:
private class ParentObject { }
private class ChildObject extends ParentObject { }
private interface Template<T extends ParentObject> {
void doSomething(T object);
}
private class TemplateImpl implements Template<ChildObject> {
public void doSomething(ChildObject object) { }
}
Run Code Online (Sandbox Code Playgroud)
因此,我有一些从Template继承的类,它们对从ParentObject继承的对象做一些事情(我在本文中仅发布了其中一个)。现在,我遇到的问题是,当我尝试生成这些模板类之一时,在尝试执行此操作时,我不断收到“不兼容的类型”错误:
private class Factory {
public <T extends ParentObject> Template<T> generate() {
return new TemplateImpl(); // here is the error
}
}
private class Service {
public <T extends ParentObject> void magic() {
Factory f = new Factory();
Template<T> a = f.generate();
}
}
Run Code Online (Sandbox Code Playgroud)
或在执行此操作时收到“未经检查的分配”警告(代码按预期的方式工作,但是如果我做错了,我宁愿解决它!)
private class AlternativeFactory {
public Template generate() {
return new TemplateImpl();
}
}
private class Service {
public <T extends ParentObject> void magic() {
AlternativeFactory af = new AlternativeFactory();
Template<T> b = af.generate(); // warning here
}
}
Run Code Online (Sandbox Code Playgroud)
有人对我如何在没有任何警告的情况下进行这项工作有任何见解吗?如果这是一个简单的类型,我还没有太多使用类型推断。我不明白的是,为什么我不能将TemplateImpl作为实现Template的Template返回?
谢谢!
编辑:事实上,我要实现的工厂看起来像这样,似乎这就是围绕类型推断的问题所在:
private class Factory {
public Template<T extends ParentObject> generate(int option) {
switch (option) {
case 1:
return new TemplateA(); // implements Template<A> where A extends ParentObject
case 2:
return new TemplateB(); // implements Template<B> where B extends ParentObject
default:
throw new IllegalArgumentException();
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:决定使用我上面提供的代码(AlternativeFactory),并仅在调用工厂的服务方法中使用SuppressWarnings,因为看来我希望实现的目标是不可能的。我知道这使用原始类型,是一种不好的做法,但是我围绕这些Template对象和AlternativeFactory进行了很多测试,包括类型检查,因此现在必须这样做。
TemplateImpl仅与兼容Template<ChildObject>,因此new TemplateImpl()不能是-的有效返回值,public <T extends ParentObject> Template<T> generate()因为T可以是的另一个子类ParentObject
最简单的更改是制作Template一个课程:
private class Template<T extends ParentObject> {
void doSomething(T object){/*implement*/}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果必须是接口,也可以使其TemplateImpl通用:
private class TemplateImpl<T extends ParentObject> implements Template<T> {
public void doSomething(ChildObject object) { }
}
Run Code Online (Sandbox Code Playgroud)
这将允许您的工厂使用type参数:
private class Factory {
public <T extends ParentObject> Template<T> generate() {
return new TemplateImpl<T>(); //T is not bound to ChildObject
}
}
Run Code Online (Sandbox Code Playgroud)
如果您只需要确保TemplateImpl只能作为Template<ChildObject>,则您的工厂方法不需要是通用的:
private class TemplateImpl implements Template<ChildObject> {
public void doSomething(ChildObject object) { }
}
//and the factory:
private class Factory {
public Template<ChildObject> generate() {
return new TemplateImpl(); //TemplateImpl is a Template<ChildObject>
}
}
Run Code Online (Sandbox Code Playgroud)
应避免使用第二种解决方案,因为它使用原始类型。
| 归档时间: |
|
| 查看次数: |
114 次 |
| 最近记录: |