简体   繁体   English

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

[英]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.

相关问题 接口如何包含在其签名或返回类型中引用接口的具体实现类型的方法? - How can an interface include a method that references the concrete implementation type of the interface in its signature or return type? ByteBuddy 泛型方法返回转换为具体类型 - ByteBuddy generic method return cast to concrete type Java 方法从泛型返回类型返回具体类型 - Java Method return concrete type from generic return type 如何在实现通用接口时返回具体类型 - How to return a concrete type when implementing a generic interface 使方法实现的返回类型比抽象方法更具体 - Making return type of method implementation more concrete than abstract method Factory具有通用方法参数,返回类型和接口 - Factory with generic method parameter, return type and interface 从接口返回类型的通用方法 - Generic method with return type from interface 如何在方法接口中返回通用类型 - How to return generic type in a method interface 如何定义一个通用包装器接口类型并将其用作Java中的方法返回类型? - How does one define a generic wrapper interface type and use it as method return type in java? 当接口方法的泛型返回使用 Java 中的具体类型实现时,如何避免“未检查覆盖”警告? - How can I avoid an "Unchecked overriding" warning when interface method's generic return is implemented with a concrete type in Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM