java 是否可以使用泛型返回类型定义接口方法和定义返回类型的具体实现?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7433279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to have an interface method defined with a generic return type and a concrete implementation define the return type?
提问by Steve
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.
我很感激关于这是否可以以某种方式工作的任何建议。我意识到我可以在接口级别而不是方法级别定义泛型类型,但如果可能的话,我想尝试让它工作。
回答by Kirk Woll
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 youjust 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. To see why, let's consider what the method signature means before you remove the <Integer>
type parameter.
该警告消息表明您在使用 Java 泛型时违反了规则。要了解原因,让我们在删除<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. The meaning of the string Integer
is completely arbitrary and would have exactly the same meaning as:
此签名意味着该方法getValue
返回一个类型的值,Integer
其中Integer
定义为您在尖括号之间定义的泛型类型参数。字符串的含义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. However, because your original type signature declared the type parameter with the name Integer
, when you removed it, you were left with:
现在,如果您要尝试编译,则会得到一个T
未定义的错误。但是,因为您的原始类型签名使用 name 声明了类型参数,所以Integer
当您删除它时,您会得到:
public Integer getValue()
Because Integer
is alreadya predefined type, the method signature is still technically legal. However, it is only an accident that the name of your type parameter happens to be the same as a type that already exists.
因为Integer
是已经预定义类型,方法签名在技术上仍是合法的。但是,您的类型参数的名称恰好与已存在的类型相同,这只是一种意外。
Furthermore, because your interface already declared a method signature withgenerics, the Java compiler generates a warning when you remove it from the implementation. 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).
此外,因为您的接口已经声明了一个带有泛型的方法签名,所以当您从实现中删除它时,Java 编译器会生成一个警告。具体来说,编译器关心的是,在基类中,方法的返回类型是(类型擦除为Object
)名为 的泛型参数Integer
,它与系统类的类型不同(也不知道是类型兼容的)命名Integer
(或java.lang.Integer
准确地说)。