自己的通用接口,在没有原始类型警告的情况下使用
Interface generic of self, use without rawtype warning
我将 class 重构为许多实现接口的东西。它工作正常,但我希望能够使用代码而不必在任何地方推断或抑制警告。
//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 用作常规 non-interface 版本。忽略警告的地方太多了,而且到处都是Item,看起来也不吸引人。
一些注意事项:
- 项目在我的申请中成为 class 没有意义。
- 在这种情况下,我可以使用 non-generic 接口,尽管它更适合它,但为了学习,我想探索这个问题。
如果有更好的方式来描述这个问题,请随时调整标题,我不确定。
每个警告都有不同的响应,因此也需要不同的补救措施。
1:界面:
public static interface Item<T extends Item> {
public T Copy();
}
这是您的项目 class 的关键功能。您希望 Item 的每个参数化实例将其自身复制到具有 same 参数化的实例中。第一个警告表明您未能执行此操作。
您应该明确要求 T 是同一类型,如下所示:
public static interface Item<T extends Item<T>> {
public T Copy();
}
2:默认项目:
public static final Item DEFAULT_ITEM = new FooItem(Color.RED);
界面中默认项目的问题在于,因为它是原始的,所以它不遵循该约束。它的 copy()
方法可能 return 一个带有 不同 参数的项目。如果你想在该项目上强制执行此操作,则需要将其声明为 FooItem,如下所示:
public static final FooItem DEFAULT_ITEM = new FooItem(Color.RED);
如果您不想公开可能提供 public 的完整签名或您认为默认项目用户不应该看到的保护方法,您可以将其隐藏在中间抽象类型下。
3:修理工
你需要问自己一些设计问题:
是否所有 RepairMen 都能修复任何项?在这种情况下,您需要通过在所有维修人员字段和方法上使用通配符 <?>
来表达这一点。
public static class RepairMan {
Item<?> itemNeedingRepairs; // Any Item is acceptable
public RepairMan(final Item<?> item) { // Any Item is acceptable
itemNeedingRepairs = item.Copy();
}
}
是否有一些 RepairMen 是专门的,比如水管工和电工,他们应该限制他们可以修理的物品类型?在这种情况下,你必须让 RepairMen 设置一些界限Item 参数。
public static class RepairMan<T extends Item<T> {
TitemNeedingRepairs;
public RepairMan(final Titem) {
itemNeedingRepairs = item.Copy();
}
}
使用边界的示例实现:
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);
}
最后的话
在构造函数中工作是 considered bad practive,并且 RepairMan 不需要您提前知道它将处理哪个 Item 实例。相反,它应该提供一种修复方法:
public void repair(Item<?> item){...}
我将 class 重构为许多实现接口的东西。它工作正常,但我希望能够使用代码而不必在任何地方推断或抑制警告。
//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 用作常规 non-interface 版本。忽略警告的地方太多了,而且到处都是Item,看起来也不吸引人。
一些注意事项:
- 项目在我的申请中成为 class 没有意义。
- 在这种情况下,我可以使用 non-generic 接口,尽管它更适合它,但为了学习,我想探索这个问题。
如果有更好的方式来描述这个问题,请随时调整标题,我不确定。
每个警告都有不同的响应,因此也需要不同的补救措施。
1:界面:
public static interface Item<T extends Item> { public T Copy(); }
这是您的项目 class 的关键功能。您希望 Item 的每个参数化实例将其自身复制到具有 same 参数化的实例中。第一个警告表明您未能执行此操作。
您应该明确要求 T 是同一类型,如下所示:
public static interface Item<T extends Item<T>> {
public T Copy();
}
2:默认项目:
public static final Item DEFAULT_ITEM = new FooItem(Color.RED);
界面中默认项目的问题在于,因为它是原始的,所以它不遵循该约束。它的 copy()
方法可能 return 一个带有 不同 参数的项目。如果你想在该项目上强制执行此操作,则需要将其声明为 FooItem,如下所示:
public static final FooItem DEFAULT_ITEM = new FooItem(Color.RED);
如果您不想公开可能提供 public 的完整签名或您认为默认项目用户不应该看到的保护方法,您可以将其隐藏在中间抽象类型下。
3:修理工
你需要问自己一些设计问题:
是否所有 RepairMen 都能修复任何项?在这种情况下,您需要通过在所有维修人员字段和方法上使用通配符 <?>
来表达这一点。
public static class RepairMan {
Item<?> itemNeedingRepairs; // Any Item is acceptable
public RepairMan(final Item<?> item) { // Any Item is acceptable
itemNeedingRepairs = item.Copy();
}
}
是否有一些 RepairMen 是专门的,比如水管工和电工,他们应该限制他们可以修理的物品类型?在这种情况下,你必须让 RepairMen 设置一些界限Item 参数。
public static class RepairMan<T extends Item<T> {
TitemNeedingRepairs;
public RepairMan(final Titem) {
itemNeedingRepairs = item.Copy();
}
}
使用边界的示例实现:
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);
}
最后的话
在构造函数中工作是 considered bad practive,并且 RepairMan 不需要您提前知道它将处理哪个 Item 实例。相反,它应该提供一种修复方法:
public void repair(Item<?> item){...}