如何在类中引用嵌套模板参数的嵌套类型?

时间:2016-12-19 06:50:48

标签: java templates generics

这是this question的后续内容。基本上,我有以下几个类:

public class Parent<B> {

    public B b;

    public Parent(B b) {
        this.b = b;
    }
}

public class Child<B> extends Parent<B> {

    public Child(B b) {
        super(b);
    }
}

我想要另一个引用它们的课程:

public class Foo<ParentType<B> extends Parent<B>, B> {
//                         ^ syntax error here: > expected
    public ParentType<B> parent;
    public B otherItem;

    public Foo(ParentType<B> parent, B otherItem) {
        this.parent = parent;
        this.otherItem = otherItem;
        B b = parent.b;
    }
}

我认为对于一个人来说,我认为上面应该做的事情是清楚的,但Java基本上认为它是一个语法混乱,从第一个嵌套的<开始。

我尝试删除类模板声明中的<B>部分:

public class Foo<ParentType extends Parent, B> {
    public ParentType<B> parent;
//         ^ (5:12)
    public B otherItem;

    public Foo(ParentType<B> parent, B otherItem) {
//                     ^ same error here
        this.parent = parent;
        this.otherItem = otherItem;
        B b = parent.b;
    }
}

但IntelliJ抱怨

  

输入&#39; ParentType&#39;没有类型参数

并且编译器给出了错误:

Error:(5, 12) java: unexpected type
  required: class
  found:    type parameter ParentType

如果我让代码看起来像这样,我最终可以解决所有错误:

public class Foo<ParentType extends Parent, B> {
    public ParentType parent;
    public B otherItem;

    public Foo(ParentType parent, B otherItem) {
        this.parent = parent;
        this.otherItem = otherItem;
        Object b = parent.b;
    }
}

但是,这不允许我确保bB,并且我希望强制执行此操作以便我可以将其传递给接受{{B的方法。例如,1}}。

我之前的问题的答案是添加更多的模板,但我只能通过删除一些代码来编译代码。有没有我失踪的伎俩?

我知道我可以通过强制转换来解决这个问题,但是如果可能的话,我希望编译器强制执行该解决方案。

1 个答案:

答案 0 :(得分:3)

仅将类型参数添加到参数化类,然后您应该实现您想要的目标:

public class Foo<ParentType extends Parent<B>, B> {
    public ParentType parent;
    public B otherItem;

    public Foo(final ParentType parent, final B otherItem) {
        this.parent = parent;
        this.otherItem = otherItem;
        final B b = parent.b;
    }
}

现在ParentType必须是Parent<B>的子类型,因此b只是B ,只要您的ParentType不覆盖它