自我界面,没有rawtype警告使用

时间:2016-10-14 09:27:56

标签: java generics warnings

我重构了一个实现接口的类。它工作正常,但我希望能够使用代码,而无需在任何地方推断或抑制警告。

//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作为常规非接口版本。有太多的地方可以添加忽略警告,而且各地的项目似乎也没有吸引力。

一些注意事项:

  1. 在我的申请中作为一个班级没有意义。
  2. 在这个例子中我可以使用非通用接口,尽管它更适合使用它,但我想为了学习而探索这个问题。
  3. 如果有更好的方法来描述这个问题,请随意调整标题,我不确定。

1 个答案:

答案 0 :(得分:0)

对每个警告有不同的回应,因此也需要不同的补救措施。

1:界面:

  

public static interface Item<T extends Item> { public T Copy(); }

这是Item类的关键功能。您希望Item的每个参数化实例将自身复制到具有相同参数化的实例中。第一个警告显示您未能强制执行此操作。

你应该明确地问T是这样的类型:

public static interface Item<T extends Item<T>> {
     public T Copy();
}

2:默认项目:

  

public static final Item DEFAULT_ITEM = new FooItem(Color.RED);

界面中默认项目的问题是,因为它是原始的,它不遵循该约束。其copy()方法可能会返回带有不同参数的Item。如果要在该Item上强制执行此操作,则需要将其声明为FooItem,如下所示:

public static final FooItem DEFAULT_ITEM = new FooItem(Color.RED);

如果您不想公开可能提供公共或受保护方法的完整签名,那么您将无法使用默认项目用户看到,您可以在中间抽象类型下隐藏它。

3:RepairMan

你需要问自己一些设计问题:

是否所有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);
}