如何使用嵌套模板参数编写类?

时间:2016-12-19 06:07:17

标签: java templates generics

我想知道如何用Java编写一个具有嵌套模板参数的类。此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 extends Parent, B> {
    public ParentType parent;
    public B otherItem;

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


public class Main {
    public static void main(String[] args) {
        Parent<String> stringParent = new Parent<>("hello");
        Child<Integer> intChild = new Child<>(5);

        Foo<Parent, String> foo = new Foo<>(stringParent, "bonjour");
        Foo<Child, Integer> childFoo = new Foo<>(intChild, 42);

        Object b = foo.parent.b;
        System.out.println(b + ", " + b.getClass());
    }
}

我被迫将foo.parent.b的类型声明为Object,即使我知道它是String(并且程序也知道它:输出为{{1} }})。我想写更像这样的代码:

hello, class java.lang.String

或类似的内容,明确强制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; } } 的类型链接到parent,但IntelliJ会抱怨B并且编译器会给出错误:

Type 'ParentType' does not have type parameters

上面标出了发生错误的位置。

1 个答案:

答案 0 :(得分:2)

这是因为您在此处未指定Parent的类型参数:

Foo<Parent, String> foo = new Foo<>(stringParent, "bonjour");
Foo<Child, Integer> childFoo = new Foo<>(intChildBar, 42);

Object b = foo.parent.b;

如果您指定Foo<Parent, String>的类型参数Parent,而不是Foo<Parent<String>, String>,那么您可以获得b的正确类型:

Foo<Parent<String>, String> foo = new Foo<>(stringParent, "bonjour");
Foo<Child, Integer> childFoo = new Foo<>(intChildBar, 42);

String b = foo.parent.b;