消除java泛型的类型参数

时间:2011-12-07 14:10:38

标签: java generics

代码:

interface Property<T>
{
    T get();
}

class BoolProperty implements Property<Boolean>
{
    @Override
    public Boolean get()
    {
        return false;
    }
}
class StringProperty implements Property<String>
{
    @Override
    public String get()
    {
        return "hello";
    }
}
class OtherStringProperty implements Property<String>
{
    @Override
    public String get()
    {
        return "bye";
    }
    public String getSpecialValue()
    {
        return "you are special";
    }
}

由我的班级使用:

class Result<P extends Property<X>, X>
{
    P p;
    List<X> list;
}

如您所见,它有两个类型参数PX。尽管如此X总是可以从P推断出来,但语言要求我同时提供:{/ p>

Result<BooleanProperty, Boolean> res = new Result<BooleanProperty, Boolean>();

有没有摆脱X类型参数的技巧?我想要使​​用

Result<BooleanProperty> res = new Result<BooleanProperty>();

此外,我不想丢失类型信息并将其用作:

Result<OtherStringProperty> res = new Result<OtherStringProperty>();
String spec = res.p.getSpecialValue();
String prop = res.list.get(0);

4 个答案:

答案 0 :(得分:4)

我会将Result类更改为

class Result<X> {
    Property<X> property;
    List<X> list;
}

我不认为编译器可以从X推断Property,因为您的Result类正在等待两个泛型的两个定义。

答案 1 :(得分:1)

您无法推断出类型,但您可以添加额外的间接级别:

class BoolProperty implements Property<Boolean>
{
    @Override
    public Boolean get()
    {
        return false;
    }
}

class Sub<X, P extends Property<X>> {
    P p;
    List<X> list;
}

class Result<X> extends Sub<X, Property<X>> {
}

Result<Boolean> res = new Result<Boolean>();
List<Boolean> list = res.list;
Boolean b = res.p.get();
List<String> res2 = res.list; // compilation error

答案 2 :(得分:0)

您是否尝试过使用通配符?

class Result<? extends Property<X>>
{
    // stuff
}

答案 3 :(得分:0)

有一个类似的问题,你可能会觉得有趣的答案:https://stackoverflow.com/a/4452268/247763

基本上,没有真正的方法可以解决包括额外泛型类型的问题,因为如果没有它,编译器就无法知道你正在使用什么类型。我猜这会破坏你的方法的目的,但你可以尝试扩展Result同时指定类型 - 类似这样:

class BoolResult extends Result<BoolProperty, Boolean> {
    // Do stuff
}