2011-09-15 28 views
9

我想创建一个接口:是否有可能使用泛型返回类型定义接口方法,并且具体实现是否定义了返回类型?

public interface OperandValue 
{ 
    <T> T getValue(); 
} 

然后,我会希望有一个具体的实现是这样的:

public class NumberOperandValue implements OperandValue 
{ 
    @Override 
    public <Integer> Integer getValue() 
    { 
     // some integer value that is set elsewhere 
     return 1; 
    } 
} 

Eclipse是强调了<Integer>给我,说一个警告:

类型参数Integer隐藏类型整数

我很欣赏任何建议,如果这可以以某种方式工作。我意识到我可以在接口级别而不是方法级别定义泛型类型,但是想尽可能地使其工作。

回答

22

你可能想接口更改为:

public interface OperandValue<T> 
{ 
    T getValue(); 
} 

而实施:

public class NumberOperandValue implements OperandValue<Integer> 
{ 
    @Override 
    public Integer getValue() 
    { 
     // some integer value that is set elsewhere 
     return 1; 
    } 
} 

现在你告诉界面你想这个方法返回什么类型。换句话说,你使接口类型是泛型的,而不是方法声明。但那似乎是你想要的。

补充说明:

public <Integer> Integer getValue() 

实际上意味着,“定义名称为‘整数’泛型类型参数”,其中getValue返回“整数”类型刚刚定义

回应史蒂夫的评论下面

,当我从我的方法实现去除<Integer>我再 得到,说一个警告:Type safety: The return type Integer for getValue() from the type NumberOperandValue needs unchecked conversion to conform to T from the type OperandValue

该警告消息表明您在使用Java泛型时会违反规则。为了明白为什么,让我们先考虑方法签名的含义,然后再删除<Integer>类型参数。

public <Integer> Integer getValue() 

这个签名意味着getValue返回Integer类型,其中Integer被定义为你的尖括号之间所界定的一般类型参数的值的方法。字符串Integer的意义完全是任意的,将具有完全相同的含义相同:

public <T> T getValue() 

为了清楚起见,让我们坚持这个版本的方法签名为你的问题的目的。当我们移除类型参数时会发生什么?

public T getValue() 

现在,如果你尝试编译,你会得到一个错误,T是不确定的。然而,因为你原来的类型签名中声明的名称Integer类型参数,当你删除它,你留下了:

public Integer getValue() 

因为Integer已经预定义的类型,方法签名仍然是技术上是合法的。然而,你的类型参数的名称恰好与已经存在的类型相同,这只是偶然的。

此外,由于您的接口已经声明了方法签名泛型,因此Java编译器在将其从实现中移除时会生成警告。具体来说,编译器担心在基类中,方法的返回类型是(类型擦除到Object)名为Integer的通用参数,该参数不是相同类型(也不知道与类型兼容)系统类名为Integer(或准确地说是java.lang.Integer)。

+0

是否有可能有一个接口方法本身通用?如果是这样,你将如何实现它? – Kal

+1

@卡尔,是的,这是可能的。但是在实现类中“插入”特定类型是不可能的。如果方法是泛型的,这意味着方法的*调用者*负责提供类型参数。 –

+0

谢谢柯克。我懂了。如果接口定义是由OP定义的,那么实现应该定义为'@Override public T getValue()'。正确? – Kal

相关问题