是否有可能使用泛型返回类型定义接口方法,并且具体实现定义返回类型? [英] Is it possible to have an interface method defined with a generic return type and a concrete implementation define the return type?

查看:337
本文介绍了是否有可能使用泛型返回类型定义接口方法,并且具体实现定义返回类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个接口:

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

然后我想要一个像这样的具体实现:

  public class NumberOperandValue implements OperandValue 
{
@Override
public< Integer>整数getValue()
{
//在某处设置的某个整数值
return 1;
}
}

Eclipse强调< ; Integer> 给了我一个警告:


类型参数Integer隐藏Integer类型 p>

感谢您提供任何建议,看看能否以某种方式工作。我意识到我可以在接口级别而不是方法级别定义泛型类型,但是希望尽可能地使其工作。

解决方案

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

并执行到:

  public class NumberOperandValue implements OperandValue< Integer> 
{
@Override
public Integer getValue()
{
//在别处设置的某个整数值
return 1;




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



附注:

  public< Integer> Integer getValue()

其实意味着'定义一个名称为Integer的泛型类型参数,其中 getValue 返回刚刚定义的 you 的Integer类型。

响应以下Steve的评论


当我从我的方法实现中移除< code>< Integer> 时,我然后
得到一个警告: Type safety:返回类型整型为
getValue()类型NumberOperandValue需要未经检查的转换
才能符合OperandValue类型中的T


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

  public< Integer>整数getValue()

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

  public< T> T getValue()

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

  public T getValue()

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

  public Integer getValue()

因为 Integer 已经是 预定义类型,方法签名在技术上仍然合法。然而,你的类型参数的名称恰好与已经存在的类型相同,这只是偶然的。另外,因为你的接口已经用泛型声明了一个方法签名,当你从实现中移除时,Java编译器会产生一个警告。具体而言,编译器担心在基类中,该方法的返回类型是( -type至 Object )泛型参数,名称为 Integer ,它与名为 Integer (或 java.lang.Integer 准确)。


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:

The type parameter Integer is hiding the type 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.

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

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.

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:

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:

public Integer getValue()

Because Integer is already a 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.

Furthermore, because your interface already declared a method signature with generics, 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).

这篇关于是否有可能使用泛型返回类型定义接口方法,并且具体实现定义返回类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆