是否可以使用generics返回类型定义接口方法,并且具体实现定义返回类型?

我想创建一个接口:

public interface OperandValue {  T getValue(); } 

我希望有一个这样的具体实现:

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

Eclipse强调给我一个警告说:

类型参数Integer隐藏了Integer类型

如果这可以以某种方式工作,我感谢任何建议。 我意识到我可以在接口级别而不是方法级别定义generics类型,但是如果可能的话,我想尝试使其工作。

您可能希望将界面更改为:

 public interface OperandValue { T getValue(); } 

并实施:

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

现在,您告诉接口您希望该方法返回什么类型。 换句话说,您将接口类型设置为generics,而不是方法声明。 但这似乎是你想要的。

作为旁注:

 public  Integer getValue() 

实际上意味着’定义一个名为“Integer”的generics类型参数,其中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

该警告消息表明您在使用Javagenerics时违反了规则。 要了解原因,请在删除类型参数之前考虑方法签名的含义。

 public  Integer getValue() 

此签名表示方法getValue返回Integer类型的值,其中Integer被定义为您在尖括号之间定义的generics类型参数。 字符串Integer的含义完全是任意的,其含义完全相同:

 public  T getValue() 

为清楚起见,为了您的问题,我们坚持使用此版本的方法签名。 删除类型参数会发生什么?

 public T getValue() 

现在,如果您尝试编译,则会收到T未定义的错误。 但是,因为您的原始类型签名声明了名称为Integer的type参数,所以当您删除它时,您将留下:

 public Integer getValue() 

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

此外,因为您的接口已经使用generics声明了方法签名,所以当您从实现中删除它时,Java编译器会生成警告。 具体来说,编译器担心在基类中,方法的返回类型是名为Integer的(类型擦除到Object )generics参数,它不是同一类型(也不知道类型兼容)系统类名为Integer (或者精确的java.lang.Integer )。