消除java泛型的类型参数

消除java泛型的类型参数,java,generics,Java,Generics,守则: interface Property<T> { T get(); } class BoolProperty implements Property<Boolean> { @Override public Boolean get() { return false; } } class StringProperty implements Property<String> { @Overrid

守则:

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";
    }
}
有什么技巧可以去掉
X
类型参数吗?我只想用它

Result<BooleanProperty> res = new Result<BooleanProperty>();
Result res=新结果();
此外,我不希望丢失类型信息并将其用作:

Result<OtherStringProperty> res = new Result<OtherStringProperty>();
String spec = res.p.getSpecialValue();
String prop = res.list.get(0);
Result res=新结果();
字符串spec=res.p.getSpecialValue();
String prop=res.list.get(0);

您是否尝试过使用通配符泛型

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

课堂结果有一个类似的问题,你可能会发现它的答案很有趣:

从本质上讲,没有真正的方法可以绕过额外的泛型类型,因为没有它,编译器无法知道您使用的是什么类型。我猜这会破坏您方法的目的,但是您可以尝试在指定类型的同时扩展
Result
,如下所示:

class BoolResult extends Result<BoolProperty, Boolean> {
    // Do stuff
}
类BoolResult扩展结果{
//做事
}

我会将
结果
类更改为

class Result<X> {
    Property<X> property;
    List<X> list;
}
类结果{
财产;
名单;
}

我认为编译器无法从
属性
推断
X
,因为您的
结果
类正在等待两个泛型的两个定义。

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

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
类BoolProperty实现属性
{
@凌驾
公共布尔get()
{
返回false;
}
}
班子{
P;
名单;
}
类结果扩展子类{
}
Result res=新结果();
列表=res.List;
布尔b=res.p.get();
List res2=res.List;//编译错误

是,但我不能在类中进一步使用它,即
列表将是非类型化的。属性子类中是否存在特定于类型的行为?如果不是,则可以通过属性接口而不是非泛型接口引用属性subclass@Gnat是的,有。我已经更新了这个问题以提及它。@derek已经链接了关于同一类型的另一个已回答问题,这解释了为什么您不能这样做。不能使用它,因为
结果
类应该知道属性的确切类型。如果可以,为什么?我想这是因为您只有首选项实现的参考之一。因为您希望它是泛型的,所以我会将其更改为引用接口首选项,而不是引用它。如果问题与接收首选项集合作为参数的方法有关,那么您只需要在链接的答案中使用通用通配符CollectionColinD“出于充分的理由”,但我不理解原因。有人知道吗?@kan-这样编译器就知道类型实际上是泛型的,而不是像示例中那样的其他具体类型(比如Double)。这只是语法问题。这可能是标记此类类型参数的一种特殊方式。为什么它不仅仅是编译器缺少的一个功能?@kan-为此,你得问问甲骨文公司的人。我希望我知道。
class Result<X> {
    Property<X> property;
    List<X> list;
}
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