Java 泛型 lt;super T>中 super 怎么 理解?与 extends 有何不同
1个回答
2017-10-29 · 【免费测试,验证码5秒必达】
北京巴卜技术有限公司
北京巴卜技术有限公司(以下简称巴卜)是具备国际水准的移动商务平台技术和应用方案提供商。自成立以来,巴卜始终 致力于为国内外企业提供具备国际技术水准的移动商务平台及运营服务。
向TA提问
关注
展开全部
java泛型是1.5引进的一个新概念.本题对于"?superT"和"?extendsT",我从书上摘个经典的例子给你看看,如果不能理解,那么你就参考以下书籍慢慢体会,循序渐进!"?superT"和"?extendsT",都是java泛型通配符,而用法又有区别,还有super和extends不是java类关系中的超类和继承的意思,他是通配符的下限和上限限制.下面看一个通配符得高级用法:在这一部分,我们来考虑一些通配符得高级用法。我们已经看到了上限通配符在从一个数据结构中进行读取的几个例子。现在考虑相反的情况,一个只写的数据结构。接口Sink是这种情况的一个简单例子。interfaceSink{voidflush(Tt);}我们可以想象他被如下面的代码一样使用。方法writeAll()被设计来把集合coll的所有元素flush到sinksnk,并且返回最后一个flush的元素。publicstaticTwriteAll(Collectioncoll,Sinksnk){Tlast=null;for(Tt:coll){last=t;snk.flush(last);}returnlast;}Sinks;Collectioncs;Stringstr=writeAll(cs,s);//非法的调用!!像上面所写,writeAll()的调用是非法的,因为没有有效的类型参数可以被推断出来。String或Object都不是T的合适的类型,因为Collection的元素和Sink的元素必须是同样的类型。我们可以解决这个问题,通过使用通配符来修改writeAll()的方法签名,如下:TwriteAll(Collectioncoll,Sinksnk){…}Stringstr=writeAll(cs,s);//可以调用但是返回值类型错误这个调用现在是合法的,但是赋值产生错误,因为推断出的返回值类型是Object因为T匹配了Sink的类型,Object。解决方案是使用一种我们还没有见过的有限制的通配符:有下限的通配符。语法?superT表示T的一个未知的父类(或者是T自己)。这跟我们用?extendsT表示T的一个未知的子类是对应的。TwriteAll(Collectioncoll,Sinksnk){…}Stringstr=writeAll(cs,s);//YES!!!使用这个语法,这个调用是合法的,推断出来的T是String,正是我们想要的。现在让我们看一个更现实的例子。一个java.util.TreeSet代表一个有序的元素是E类型的树。创建一个TreeSet的一个方法是传递一个Comparator对象给构造函数。这个Comparator将会用来按照需要对TreeSet进行排序。TreeSet(Comparatorc)Comparator接口是核心:interfaceComparator{intcompare(Tfst,Tsnd);}假定我们要创建一个TreeSet并传递一个合适的Comparator,我们需要传一个能比较String的Comparator。这可以是一个Comparator,也可以是一个Comparator。然而我们不能用Comparator来调用上面的构造函数。我们可以使用一个有下限的通配符来得到我们需要的灵活性:TreeSet(Comparatorc)这允许任何可用的Comparator被传递进去。作为使用下限通配符最终的例子,让我们来看看方法Collections.max(),它返回一个集合中的最大的元素。现在,为了让max()能工作,传进来的集合中的所有元素必须实现Comparatable接口。而且,他们必须都能够被彼此比较(allbecomparabletoeachother)。第一个尝试是:publicstatic>Tmax(Collectioncoll)就是说,方法的参数是某一个能和自己进行比较的T的集合。这限制太严格了。为什么?考虑一个能和任何对象进行比较的类型:classFooimplementsComparable{}Collectioncf=;Collections.max(cf);//应该能工作cf中的每个元素都可以和每个cf中的其他元素进行比较,因为每个这样的元素都是一个Foo,它可以和任意的对象进行比较,也可以和另一个Foo进行比较。但是,使用上面的方法签名,我们发现这个调用被拒绝。推断出来的类型必须是Foo,但是Foo没有实现接口Comparable。T精确的(exactly)和自己能比较是不需要的。所需要的是T能够和它的父类中的一个进行比较,这导出:(注:Collections.max()的实际方法签名更复杂,我们在第10部分再讨论。)publicstatic>Tmax(Collectioncoll)这个推论对大多数想让Comparable对任意类型生效的用法中都有效:你总是应该使用Comparable。总之,如果你有一个只使用类型参数T作为参数的API,它的使用应该利用下限通配符(?superT)的好处。相反的,如果API只返回T,你应该使用上限通配符(?extendsT)来给你的客户端更大的灵活性。(原文:ThisreasoningappliestoalmostanyusageofComparablethatisintendedtoworkforarbitrarytypes:YoualwayswanttouseComparable.Ingeneral,ifyouhaveanAPIthatonlyusesatypeparameterTasanargument,itsusesshouldtakeadvantageoflowerboundedwildcards(?superT).Conversely,iftheAPIonlyreturnsT,you'llgiveyourclientsmoreflexibilitybyusingupperboundedwildcards(?extendsT).)。
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询