如何引用通用参数自己的参数,例如T2 <t>中的T?

时间:2018-12-06 14:05:04

标签: java generics inheritance

考虑以下界面:

class SomeParamClass<T> {
    public T getT() {return null;}
}
class GetThing<T, TSomeImpl extends SomeParamClass<T>> {
    TSomeImpl thingcreator;
    GetThing(TSomeImpl thingcreator) {
        this.thingcreator = thingcreator;
    }
    T getThing() {
        return thingcreator.get(offset);
    }
    TSomeImpl getOrigClass() {
        return thingcreator;
    }
}

这只是我已经遇到几次问题的一个例子。

在此示例中,类型T直接绑定到参数TSomeImpl。如果您这样创建它:

new GetThing<String,TSomeImpl<String>>(new TSomeImpl<String>())

参数String不必要地重复。它是冗余,但是Java在这种情况下似乎需要它。

有没有办法将通用参数内部参数用作类型?

我组成了这种语法,有没有一种实际适用的语法?

// Pseudocode on refering to generic parameter's parameters
class GetThing<TSomeImpl extends SomeParamClass<T>, TSomeImpl::<T>> {
    TSomeImpl thingcreator;
    GetThing(TSomeImpl thingcreator) {
        this.thingcreator = thingcreator;
    }
    TSomeImpl::<T> getThing() {
        return thingcreator.get(offset);
    }
    TSomeImpl getOrigClass() {
        return thingcreator;
    }
}

那将被用作:

GetThing<TSomeImpl<String>>

不需要其他参数。

要澄清:我该如何重写原始类,使其仅具有一个通用参数List<T>并推断出T参数,因为它是从List<T>清楚地知道。

4 个答案:

答案 0 :(得分:1)

这是什么

interface SomeType<T> {
    T getT();
}

class SomeParamClass<T> implements SomeType<T> {
    public T getT() {return null;}
}

class GetThing<T> {
    SomeType<T> thingcreator;
    GetThing(SomeType<T> thingcreator) {
        this.thingcreator = thingcreator;
    }
    T getThing() {
        return thingcreator.getT();
    }
    SomeType<T> getOrigClass() {
        return thingcreator;
    }
}

您可以像这样使用它

new GetThing<String>(new SomeParamClass<>());

答案 1 :(得分:0)

问题是您正在尝试使用TList作为某种别名。那不是泛型的用途。

泛型类型参数就是:参数。无法隐藏参数。它们必须是明确的。

这是怎么了?为什么它不能满足您的要求?

class GetListEntry<T>
{
    List<T> list;
    GetListEntry(List<T> list) {
        this.list = list;
    }
    T getValueAt(int offset) {
        return list.get(offset);
    }
}

答案 2 :(得分:0)

也许我不理解问题,但是TList的作用是什么?看起来像是多余的定义。不会像这样的工作:

public class ListOfSomething<T> {

private List<T> things;

public ListOfSomething(List<T> things) {
    super();
    this.things = things;
}

T getValueAt(int offset) {
    return this.things.get(offset);
}

}

答案 3 :(得分:0)

我会推荐迈克尔斯的答案。似乎没有明显的理由让您屏蔽这样的列表。但是,如果您真的想这样做,我相信您可以通过在变量声明中省略通用参数来做到这一点。您需要指定的唯一位置是构造函数的参数。因此,只需使用

GetListEntry test = new GetListEntry(new ArrayList<String>());

应该工作正常。

您可以在this java online compiler上尝试我的测试代码。那就是我尝试过的地方,而且效果很好。

import java.util.List;
import java.util.ArrayList;

public class MyClass {
    public static void main(String args[]) {
        ArrayList<String> stringList = new ArrayList<String>();
        stringList.add("1");
        stringList.add("2");
        stringList.add("3");

        GetListEntry test = new GetListEntry(stringList);

        for(int i = 0; i <= 2; i++)
            System.out.println(test.getValueAt(i));

    }

    static class GetListEntry<T, TList extends List<T>> {
        TList list;
        GetListEntry(TList list) {
            this.list = list;
        }
        T getValueAt(int offset) {
            return list.get(offset);
        }
    }
}

如您所说,该信息是多余的。因此,所需信息从已经提到的地方获取。即,ArrayList的通用类型。