[英]Is it possible to have an interface method defined with a generic return type and a concrete implementation define the return type?
I have would like to create an interface: 我想创建一个接口:
public interface OperandValue
{
<T> T getValue();
}
I would then like to have a concrete implementation like this: 我希望有一个像这样的具体实现:
public class NumberOperandValue implements OperandValue
{
@Override
public <Integer> Integer getValue()
{
// some integer value that is set elsewhere
return 1;
}
}
Eclipse is underlining the <Integer>
giving me a warning that says: Eclipse强调<Integer>
给我一个警告说:
The type parameter Integer is hiding the type Integer 类型参数Integer隐藏了Integer类型
I appreciate any suggestions on if this can work somehow. 如果这可以以某种方式工作,我感谢任何建议。 I realize that I could define the generic type at the interface level and not the method level, but would like to try to get this to work if possible. 我意识到我可以在接口级别而不是方法级别定义泛型类型,但是如果可能的话,我想尝试使其工作。
You probably want to change the interface to: 您可能希望将界面更改为:
public interface OperandValue<T>
{
T getValue();
}
And the implementation to: 并实施:
public class NumberOperandValue implements OperandValue<Integer>
{
@Override
public Integer getValue()
{
// some integer value that is set elsewhere
return 1;
}
}
Now you're telling the interface what type you want that method to return. 现在,您告诉界面您希望该方法返回的类型。 In other words, you're making the interface type generic, rather than the method declaration. 换句话说,您将接口类型设为泛型,而不是方法声明。 But that seems to be what you want. 但这似乎是你想要的。
As a side note: 作为旁注:
public <Integer> Integer getValue()
Actually means, 'define a generic type parameter with the name "Integer"' where getValue
returns the "Integer" type that you just defined. 实际上意味着'定义一个名为“Integer”的泛型类型参数,其中getValue
返回您刚刚定义的“Integer”类型。
Responding To Steve's Comments Below : 回应史蒂夫的评论如下 :
when I remove the
<Integer>
from my method implementation that I then get a warning that says:Type safety: The return type Integer for getValue() from the type NumberOperandValue needs unchecked conversion to conform to T from the type OperandValue
当我从我的方法实现中删除<Integer>
然后我得到一个警告:Type safety: The return type Integer for getValue() from the type NumberOperandValue needs unchecked conversion to conform to T from the type OperandValue
That warning message indicates that you're breaking the rules when using Java generics. 该警告消息表明您在使用Java泛型时违反了规则。 To see why, let's consider what the method signature means before you remove the <Integer>
type parameter. 要了解原因,请在删除<Integer>
类型参数之前考虑方法签名的含义。
public <Integer> Integer getValue()
This signature means that the method getValue
returns a value of type Integer
where Integer
is defined as the generic type parameter you defined between the angle brackets. 此签名表示方法getValue
返回Integer
类型的值,其中Integer
被定义为您在尖括号之间定义的泛型类型参数。 The meaning of the string Integer
is completely arbitrary and would have exactly the same meaning as: 字符串Integer
的含义完全是任意的,其含义与:
public <T> T getValue()
For clarity, let's stick with this version of your method signature for the purposes of your question. 为清楚起见,为了您的问题,我们坚持使用此版本的方法签名。 What happens when we remove the type parameter? 删除类型参数会发生什么?
public T getValue()
Now if you were to try to compile, you'd get an error that T
is undefined. 现在,如果您尝试编译,则会收到T
未定义的错误。 However, because your original type signature declared the type parameter with the name Integer
, when you removed it, you were left with: 但是,因为您的原始类型签名声明了名称为Integer
的type参数,所以当您删除它时,您将留下:
public Integer getValue()
Because Integer
is already a predefined type, the method signature is still technically legal. 因为Integer
已经是预定义类型,所以方法签名在技术上仍然是合法的。 However, it is only an accident that the name of your type parameter happens to be the same as a type that already exists. 但是,类型参数的名称恰好与已存在的类型相同,这只是一个意外。
Furthermore, because your interface already declared a method signature with generics, the Java compiler generates a warning when you remove it from the implementation. 此外,因为您的接口已经使用泛型声明了方法签名,所以当您从实现中删除它时,Java编译器会生成警告。 Specifically, the compiler is concerned that in the base class, the return type of the method is the (type-erased to Object
) generic parameter named Integer
, which is not the same type (nor is it known to be type compatible with) the system class named Integer
(or java.lang.Integer
to be precise). 具体来说,编译器担心在基类中,方法的返回类型是名为Integer
的(类型擦除到Object
)泛型参数,它不是同一类型(也不知道类型兼容)系统类名为Integer
(或精确的java.lang.Integer
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.