我重构了一个实现接口的类。它工作正常,但我希望能够使用代码,而无需在任何地方推断或抑制警告。
//Item is a raw type. References to generic type Item<T> should be parameterized.
public interface Item<T extends Item>
{
// Item is a raw type. References to generic type Item<T> should be parameterized.
public static final Item DEFAULT_ITEM = new FooItem(Color.RED);
// Because using "something = new Item(Default_Item)" won't work.
public T Copy();
public void Foo();
public void Bar();
}
public class RepairMan
{
// Item is a raw type. References to generic type Item<T> should be parameterized.
Item itemNeedingRepairs;
// Item is a raw type. References to generic type Item<T> should be parameterized.
public RepairMan(final Item item)
{
itemNeedingRepairs = item.Copy();
}
}
我希望能够在大多数代码中使用Item作为常规非接口版本。有太多的地方可以添加忽略警告,而且各地的项目似乎也没有吸引力。
一些注意事项:
如果有更好的方法来描述这个问题,请随意调整标题,我不确定。
答案 0 :(得分:0)
对每个警告有不同的回应,因此也需要不同的补救措施。
public static interface Item<T extends Item> { public T Copy(); }
这是Item类的关键功能。您希望Item的每个参数化实例将自身复制到具有相同参数化的实例中。第一个警告显示您未能强制执行此操作。
你应该明确地问T是这样的类型:
public static interface Item<T extends Item<T>> {
public T Copy();
}
public static final Item DEFAULT_ITEM = new FooItem(Color.RED);
界面中默认项目的问题是,因为它是原始的,它不遵循该约束。其copy()
方法可能会返回带有不同参数的Item。如果要在该Item上强制执行此操作,则需要将其声明为FooItem,如下所示:
public static final FooItem DEFAULT_ITEM = new FooItem(Color.RED);
如果您不想公开可能提供公共或受保护方法的完整签名,那么您将无法使用默认项目用户看到,您可以在中间抽象类型下隐藏它。
你需要问自己一些设计问题:
是否所有RepairMen都能修复任何项目?在这种情况下,您需要通过使用公式{{1}来表达它在你所有修理人员的领域和方法上。
<?>
某些RepairMen是专业的,比如水管工和电工,它们应该限制他们可以修复的项目类型吗?在这种情况下,你必须让RepairMen在Item参数上设置一些界限。 / p>
public static class RepairMan {
Item<?> itemNeedingRepairs; // Any Item is acceptable
public RepairMan(final Item<?> item) { // Any Item is acceptable
itemNeedingRepairs = item.Copy();
}
}
使用边界的示例实现:
public static class RepairMan<T extends Item<T> {
TitemNeedingRepairs;
public RepairMan(final Titem) {
itemNeedingRepairs = item.Copy();
}
}
在构造函数中进行工作是considered bad practive,并且RepairMan不需要事先知道它将处理哪个Item实例。相反,它应该提供修复方法:
public static interface ElectricItem extends Item<ElectricItem>{}
public static class LightBulb implements ElectricItem{
@Override
public LightBulb Copy() {
return new LightBulb();
}
}
public static class Electrician extends RepairMan<ElectricItem>{
ElectricItem itemNeedingRepairs; // Only electric Items acceptable
public Electrician(ElectricItem item) {
super(item);
}
}
public static void main(String[] argc){
LightBulb bulb = new LightBulb();
new Electrician(bulb);
}