如何引用泛型参数本身的参数,例如t2< t>中的t?

bfnvny8b  于 2021-06-30  发布在  Java
关注(0)|答案(4)|浏览(336)

考虑以下接口:

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> .

lh80um4z

lh80um4z1#

这个怎么样

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<>());
z31licg0

z31licg02#

也许我不明白这个问题,但它是为了什么?看起来是多余的定义。像这样的事情不管用吗:

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);
}

}

fslejnso

fslejnso3#

我会参考迈克尔的答案。你似乎没有明显的理由那样掩饰你的清单。但是,如果您真的想这样做,我相信您可以通过在变量声明中省略泛型参数来实现。唯一需要指定的地方是构造函数的参数。所以,只是使用

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

应该很管用。
您可以在这个java在线编译器上尝试我的测试代码。那是我试过的地方,效果很好。

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的泛型类型。

uz75evzq

uz75evzq4#

问题是你想用 TList 作为某种别名。那不是泛型的用途。
泛型类型参数就是:参数。无法隐藏参数。它们必须是明确的。
这个怎么了?为什么不能满足你的要求?

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

相关问题