【问题标题】:Java type parameter is hiding a generic type?Java类型参数隐藏了泛型类型?
【发布时间】:2013-06-27 13:25:08
【问题描述】:

我有一个通用类:

public class Widget<COMMAND> {
    // ...
}

所以我可以创建它的实例:

Widget<Fizz> fizzWidget = new Widget<Fizz>();

然后我有一个 ABC BaseWidgetProcessor,我想接受任何类型的 Widgets:

public abstract class BaseWidgetProcessor<Widget<COMMAND>> {
    public abstract COMMAND process();
}

使用具体的实现:

public abstract class AstroWidgetProcessor<Widget<COMMAND>> {
    @Override
    public COMMAND process() {
        // ...
    }
}

等等

问题是,BaseWidgetProcessor:

public abstract class BaseWidgetProcessor<Widget<COMMAND>> {
    public abstract COMMAND process();
}

我收到语法错误:

令牌语法错误,结构错位

当我将其更改为:

public abstract class BaseWidgetProcessor<Widget> {
    public abstract COMMAND process();
}

错误消失了,但现在我收到编译器警告:

类型参数Widget隐藏了类型Widget

这是怎么回事?!?为什么会出现错误,然后是相应的警告?设置它的正确(语法)方法是什么?

【问题讨论】:

  • 哈哈。 Fizzwidget。 “你们这些该死的孩子!滚出我的草坪!哇!Fizzwidget!”
  • 对不起大家 - 我做了一个更正
  • 试试public abstract &lt;COMMAND, T extends Widget&lt;COMMAND&gt;&gt; BaseWidget&lt;T&gt;?
  • 拥有一个常量(通用)参数有什么意义?如果 *WidgetProcessors 总是有 Widget 作为参数,只需去掉 Widget 参数
  • class BaseWidgetProcessor&lt;Widget&lt;COMMAND&gt;&gt; 中,Widget 表示type parameter,而不是class type

标签: java generics


【解决方案1】:

我认为您正在寻找的是:

public abstract class BaseWidgetProcessor<W extends Widget<C>, C> {
    public abstract C process(W widget);
}

我添加了W widget 作为参数以显示更好的用法。

现在假设您有一个名为 CoolWidget 的小部件:

public class CoolWidget extends Widget<Integer> {}

要声明 CoolWidgetProcessor,您必须这样做:

public class CoolWidgetProcessor extends BaseWidgetProcessor<CoolWidget, Integer> {
    @Override
    public Integer process(CoolWidget widget) {
        // ...
    }
}

【讨论】:

  • +1 这是最通用的解决方案,但如果 OP 不需要自己生成已处理小部件的类型,则最好使用 Bohemian。
【解决方案2】:

试试这个:

public abstract class BaseWidgetProcessor<COMMAND> {

    protected Widget<COMMAND> widget;

    public BaseWidgetProcessor(Widget<COMMAND> widget) {
        this.widget = widget;
    }

    // presumably uses widget
    public abstract COMMAND process();
}

【讨论】:

  • 感谢@Bohemian (+1) - 这很有效。你能解释一下为什么(我很好奇,想比我目前的理解更好地学习泛型)。让 WidgetProcessor 扩展 Widget 的逻辑意义是什么?!?再次感谢!
  • 确实,让 FooProcessor 扩展 Foo 的逻辑意义是什么?编辑:+1 组合方法。
  • 我开始感觉到我的问题建模错误。我应该完全放弃 Widget 上的泛型类型吗?所以不是Widget&lt;Command&gt;,而是让Widget成为一个非通用接口?如果不是,那么为我的问题建模的正确方法是什么?
  • @PaulBellora 完成。 (删除它)。仅仅因为它编译并没有使它成为一个“好的答案”。如果您看到 OP 稍后的评论,实际上可能弊大于利。
  • @TicketMonster 我无法回答您的评论,因为您还没有告诉我们您想要做什么/解决什么。我可能会说,如果 Widget 对/使用类型做事,那么它应该是通用的。您在没有上下文的情况下直接跳入代码和编译器错误:也许为您的问题添加更多前言。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多