当前位置: 首页 > news >正文

网站内容管理系统使用说明书漯河seo公司

网站内容管理系统使用说明书,漯河seo公司,高境网站建设,网站布局策划文章目录 泛型的传参若函数里的参数使用基类接受所有的派生类,怎么做? 类型通配符的上限类型通配符的下限 泛型的传参 注意 若类 Base 是类 Derived 的基类(父类),那么数组类型 Base[] 是 Derived[] 的基类&#xff0…

文章目录

    • 泛型的传参
      • 若函数里的参数使用基类接受所有的派生类,怎么做?
    • 类型通配符的上限
    • 类型通配符的下限

泛型的传参

注意
若类 Base 是类 Derived 的基类(父类),那么数组类型 Base[] 是 Derived[] 的基类(父类)。但是集合类型 List<Base> 不是 List<Derived> 的基类(父类)。

若函数里的参数使用基类接受所有的派生类,怎么做?

例如:函数里的参数要接受所有的List类,包括 List<Integer>, List<String> 等。

public class Test01 {public static void main(String[] args) {ArrayList<String> strList = new ArrayList<String>();strList.add("good");strList.add("man");strList.add("helo");testGenericParameter(strList);}
// 形参类型 可以使用  List (会有警告),List<?> (推荐,没有警告), 不可以使用 List<Object>private static void testGenericParameter(List<?> list) {for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}}
}	

例如:Shape 是基类,Circle、Rectangle 是派生类
只想要接受所有Shape派生类的入参

//  ? extends Shape   表示 所有从Shape派生出的类
void testGenericParameter(List<? extends Shape> list) {}
  • ? extends Shape 表示 所有 Shape 的派生类
  • ? super Shape 表示所有 Shape 的基类(父类)

类型通配符的上限

List<? extends Shape> 是受限制通配符的例子,此处的问号(? )代表一个未知的类型,就像前面看到的通配符一样。但是此处的这个未知类型一定是Shape的子类型(也可以是Shape本身),因此可以把Shape称为这个通配符的上限(upper bound)。
类似地,由于程序无法确定这个受限制的通配符的具体类型,所以不能把Shape对象或其子类的对象加入这个泛型集合中。例如,下面代码就是错误的
在这里插入图片描述

与使用普通通配符相似的是,shapes.add()的第二个参数类型是 ? extends Shape,它表示Shape未知的子类,程序无法确定这个类型是什么,所以无法将任何对象添加到这种集合中。
简而言之,这种指定通配符上限的集合,只能从集合中取元素(取出的元素总是上限的类型或其子类),不能向集合中添加元素(因为编译器没法确定集合元素实际是哪种子类型)。
对于更广泛的泛型类来说,指定通配符上限就是为了支持类型型变。比如Foo是Bar的子类,这样A<Foo> 就相当于A<? extends Bar> 的子类,可以将A<Foo> 赋值给A<? extends Bar> 类型的变量,这种型变方式被称为协变

对于协变的泛型而言,它只能调用泛型类型作为返回值类型的方法(编译器会将该方法返回值当成通配符上限的类型);而不能调用泛型类型作为参数的方法。 口诀是:协变只出不进!

提示:没有指定通配符上限的泛型类,相当于通配符上限是Object 。例如 List<?> 表示 类型上限是Object

类型通配符的下限

除可以指定通配符的上限之外,Java也允许指定通配符的下限,通配符的下限用<? super 类型> 的方式来指定,通配符下限的作用与通配符上限的作用恰好相反。
指定通配符的下限就是为了支持类型型变。比如Foo是Bar的子类,当程序需要一个A<? super Foo> 变量时,程序可以将A<Bar> 、A<Object> 赋值给A<? super Foo> 类型的变量,这种型变方式被称为逆变
对于逆变的泛型集合来说,编译器只知道集合元素是下限的父类型,但具体是哪种父类型则不确定。因此,这种逆变的泛型集合能向其中添加元素(因为实际赋值的集合元素总是逆变声明的父类),从集合中取元素时只能被当成Object类型处理(编译器无法确定取出的到底是哪个父类的对象)。

对于逆变的泛型而言,它只能调用泛型类型作为参数的方法;而不能调用泛型类型作为返回值类型的方法。 口诀是:逆变只进不出!

设自己实现一个工具方法:实现将src集合中的元素复制到dest集合的功能,因为dest集合可以保存src集合中的所有元素,所以dest集合元素的类型应该是src集合元素类型的父类。
对于上面的copy()方法,可以这样理解两个集合参数之间的依赖关系:不管src集合元素的类型是什么,只要dest集合元素的类型与前者相同或者是前者的父类即可,此时通配符的下限就有了用武之地。
下面程序采用通配符下限的方式来实现该copy()方法。

public class TestGenericType {public static void main(String[] args) {ArrayList<Number> list1 = new ArrayList<Number>();ArrayList<Integer> list2 = new ArrayList<Integer>();list2.add(1);list2.add(2);list2.add(3);Integer last = copy(list1, list2);//①System.out.println(list1);}// dest 集合里的元素的类型必须是 src 集合元素的类型 或 其父类public static <T> T copy(Collection<? super T> dest, Collection<T> src) {T last = null;for (T ele : src) {last = ele;//逆变的泛型集合添加元素是安全的dest.add(ele);}return last;}
}

使用这种语句,就可以保证程序的①处调用后推断出最后一个被复制的元素类型是Integer,而不是笼统的Number类型。

实际上,Java集合框架中的TreeSet< E> 有一个构造器也用到了这种设定通配符下限的语法,如下所示。

    public TreeSet(Comparator<? super E> comparator) {//...}

正如前一章所介绍的,TreeSet会对集合中的元素按自然顺序或定制顺序进行排序。如果需要TreeSet对集合中的所有元素进行定制排序,则要求TreeSet对象有一个与之关联的Comparator对象。上面构造器中的参数comparator就是进行定制排序的Comparator对象。
Comparator接口也是一个带泛型声明的接口

public interface Comparator<T> {int compare(T o1, T o2);
}

通过这种带下限的通配符的语法,可以在创建TreeSet对象时灵活地选择合适的Comparator。
假定需要创建一个TreeSet<String> 集合,并传入一个可以比较String大小的Comparator,这个Comparator既可以是Comparator<String> ,也可以是Comparator<Object> 只要尖括号里传入的类型是String的父类型(或它本身)即可。

	private static void test02() {// 既可以使用 new Comparator<Object> 因为 Object 是 String 的父类,也可以使用 Comparator<String> 作为构造器的参数TreeSet<String> set1 = new TreeSet<String>(new Comparator<Object>() {@Overridepublic int compare(Object o1, Object o2) {return o1.hashCode() > o2.hashCode() ? 1 :o1.hashCode() < o2.hashCode() ? -1 : 0;}});set1.add("hello");set1.add("wa");TreeSet<String> set2 = new TreeSet<String>(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return o1.length() > o2.length() ? -1 :o1.length() < o2.length() ? 1 : 0;}});set2.add("hello");set2.add("wa");System.out.println(set1);System.out.println(set2);}

通过使用这种通配符下限的方式来定义TreeSet构造器的参数,就可以将所有可用的Comparator作为参数传入,从而增加了程序的活性。当然,不仅TreeSet有这种用法,TreeMap也有类似的用法,具体的请查阅Java的API文档。

http://www.mmbaike.com/news/43270.html

相关文章:

  • u钙网logo免费设计在线生成深圳优化公司排名
  • 婚纱摄影团购网站模板关键词排名优化易下拉技术
  • 喜欢做木工 网站营销网站建设专家
  • 做网站的技术西安最新消息今天
  • 网站源码可以做淘宝客2345电脑版网址导航
  • 公司做网站百度网址安全检测中心
  • tomcat安装wordpress优化网站的步骤
  • php 搭建手机网站综合查询
  • 网站建设工作进度表推广竞价账户托管
  • php网站是什么网络推销平台有哪些
  • 做网站要用到什么百度怎么发布广告
  • 做网站是自己公司做好还是外包好国家卫健委最新疫情报告
  • php网站建设seo排名点击 seo查询
  • 大连网站设计seo在线工具
  • 门户网站平台建设方案最新清远发布
  • 东莞宣传册设计百度seo分析工具
  • 网站导航三角怎么做seo推广优势
  • wordpress适合做企业站湖南网站建设加盟代理
  • 女网友叫我一起做优惠券网站网站关键词怎样优化
  • 做一个网站需要投入多少钱怎样宣传自己的产品
  • 建筑工程东莞网站建设seo推广怎么收费
  • 中企动力做网站的价格北京软件开发公司
  • 外贸网站建设注意什么怎样建立一个网站
  • 手机网站做安卓客户端windows优化大师使用方法
  • 免费建立公司网站seo营销培训
  • 合肥企业网站制作西安网站外包
  • 平台网站怎么建设南宁网络推广有限公司
  • 推广网站平台有哪些嘉兴网站建设
  • 聊城网站那家做的好媒体:多地新增感染趋势回落
  • 百度联盟 网站备案信息搜索引擎营销的步骤