ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

返回类型为Java Generic方法的上限和下限通配符

2019-08-28 00:03:33  阅读:179  来源: 互联网

标签:generic-method java generics wildcard


我试图解决一个我无法理解部分答案的问题.

以下是BackLister类:

public class BackLister {
    // INSERT HERE
    {
        List<T> output = new LinkedList<T>();
        for (T t : input)
            output.add(0, t);
        return output;
    }
}

这个问题询问哪些可以插入//在这里插入BackLister类来编译和运行而没有错误?

以下是选项:

A. public static <T> List<T> backwards(List<T> input)
B. public static <T> List<T> backwards(List<? extends T> input)
C. public static <T> List<T> backwards(List<? super T> input)
D. public static <T> List<? extends T> backwards(List<T> input)
E. public static <T> List<? super T> backwards(List<T> input)
F. public static <? extends T> List<T> backwards(List<T> input)
G. public static <? super T> List<T> backwards(List<T> input)

我理解A和B是正确的,因为for(T t:input)工作输入中的元素应该是T的类型或T的子类型.

但我无法理解为什么D和E选项是正确的?

我理解以下内容:

> public static< T>名单&LT ;?延伸T>向后(列表< T>输入)
    表示返回类型应该是T或子类的List
    的
> public static< T>名单&LT ;?超级T>向后(List< T> input)表示返回类型应该是T或者List
T的超类

有人可以帮我理解吗?

解决方法:

每个人之间都存在差异,我将解释他们中的大多数.让我们从我们的例子开始.我使用这个类层次结构:

class Food {}
class Apple extends Food {}
class Orange extends Food {}
class RedApple extends Apple {}

List<Food> listFood = new ArrayList<>();
List<Apple> listApple = new ArrayList<>();
List<Orange> listOrange = new ArrayList<>();
List<RedApple> listRedApple = new ArrayList<>();

从第一个开始:

A. public static <T> List<T> backwards(List<T> input)

该方法仅接受List< T>.并返回List< T>并且您无法发送listApple并返回listRedApple. (但是你的返回列表可以包含RedApple,因为它扩展了Apple,但列表类型必须是List< Apple>而不是其他)

B. public static <T> List<T> backwards(List<? extends T> input)

你可以发送listRedApple并返回listApple但你知道listRedApple是“?extend Apple”所以在方法体中java将T识别为Apple.然后如果你使用可以在listRedApple中添加作为参数发送的元素,你可以在listRedApple中添加Apple,这不是真的!所以编译器避免它并给出编译错误.在B中,您只能读取元素(并将其作为T),但您无法添加任何内容.

C. public static <T> List<T> backwards(List<? super T> input) 

您可以发送listApple,然后在方法体中,您可以添加任何扩展Apple,因为编译器将T视为Apple,并且在任何超级T的列表中,您可以添加任何扩展Apple.
但是这一次,你不能阅读任何东西,因为你不知道它的类型,除非你把它作为对象. (这是“超级T”的清单)

正如你在这里看到的那样有区别?超级和?延伸.其中一个给你写访问权限,其他给你读取权限.这是通配符的真实用途.

D. public static <T> List<? extends T> backwards(List<T> input)
E. public static <T> List<? super T> backwards(List<T> input)   

如果你发送listApple然后你返回List<?扩展Apple>但你可以将它分配给listFood或listApple或listRedApple中的任何一个,因为List<?扩展Apple>可能包含Apple或RedApple或其他内容,我们无法将其分配给任何List< T>因为那时我们可以将T添加到该列表中,也许T和?扩展T不一样.这对于D和E都是相同的.您可以将其分配给List<?扩展Apple>为’E和列表<?超级Apple>对于D并将它们发送到需要它们作为参数的方法.

F. public static <? extends T> List<T> backwards(List<T> input)
G. public static <? super T> List<T> backwards(List<T> input)

给出编译错误,因为通配符不能像这样使用.

我希望这对你有帮助.
如果出现问题,任何评论都表示赞赏.

标签:generic-method,java,generics,wildcard
来源: https://codeday.me/bug/20190827/1745964.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有