为什么80%的码农都做不了架构师?>>>   

在前面的例子中,可以使用任意类替换类型参数。对于大多数情况这很好,但是限制能够传递给类型参数的类型有时是有用的。例如,假设希望创建一个类,而且这个类中包含一个返回数组中数字平均值的方法。希望该方法可以计算任意类型数字的平均值,包含整形、单精度浮点型以及双精度浮点型。因此,希望使用类型参数以泛型化的方式指定数字类型。见示例:

package test;public class Stats<T> {private T[] nums;public Stats(T[] o) {nums = o;}public double average() {double sum = 0d;for(int i = 0; i < nums.length; i++)sum += nums[i].doubleValue();        //这里是错误的return sum /nums.length;}
}

在Stats类中,average()方法通过调用doubleValue(),试图获得nums数组中每个数字的double版本,因为所有数值类,比如Integer以及Double,都是Number的子类,而Number定义了doubleValue()方法,所以所有数值类型的封装器都可以使用该方法。问题是编译器不知道你正试图创建只使用数值类型的Stats对象。因此,当试图编译Stats时,会报错误,指出doubleValue()方法是未知的。为了解决这个问题,需要以某种方式告诉编译器,你打算只向T传递数值类型。此外,需要以某种方式确保实际上只传递了数值类型。

为了处理这种情况,java提供了有界类型(dounded type)。在指定类型参数时,可以创建声明超类的上界注:在声明时,这里只有上界,也就是使用extends,没有下界,也就是不能使用super。泛型中什么时候会使用super关键字,我们后面会讲到!),所有类型参数都必须派生自超类。这是当指定类型参数时使用extends子句完成的,如下所示:

<T extends superclass>

这样就指定T只能被superclass其子类替代。因此,superclass定义了包括superclass在内的上限。针对上例,我们可以通过将Number指定为上界,修复前面显示的Stats类,示例如下:

package test;public class Stats<T extends Number> {private T[] nums;public Stats(T[] o) {nums = o;}public double average() {double sum = 0d;for(int i = 0; i < nums.length; i++)sum += nums[i].doubleValue();    return sum /nums.length;}
}
package test;public class BoundsDemo {public static void main(String[] args) {Integer inums[] = {1,2,3,4,5};Stats<Integer> iob = new Stats<>(inums);double v = iob.average();System.out.println("iob average is " + v);Double dnums[] = {1.1,2.2,3.3,4.4,5.5};Stats<Double> dob = new Stats<>(dnums);double w = dob.average();System.out.println("dob average is " + w);}
}

注意现在使用下面这行代码声明Stats的方式:

public class Stats<T extends Number> {......}

现在使用Number对类型T进行了限定,java编译器知道所有T类型的对象都可以调用doubleValue()方法,因为该方法是由Number声明的。

除了使用类作为边界之外,也可以使用接口。实际上,可以指定多个接口作为边界。此外,边界可以包含一个类和一个或多个接口。对于这种情况,必须首先指定类类型,也就是把类类型放在extends之后的第一个位置。如果边界包含接口类型,那么只有实现了那种接口的类型参数是合法的。当指定具有一个类和一个或多个接口的边界时,使用&运算符连接它们。如下:

class Gen<T extends MyClass & MyInterface> {......}

在此,通过类MyClass和接口MyInterface对T进行限制。因此,所有传递给T的类型参数都必须是MyClass的子类,并且必须实现MyInterface接口。

转载于:https://my.oschina.net/fhd/blog/290122

java泛型之有界类型相关推荐

  1. java泛型程序设计——通配符类型+通配符的超类型限定

    [0]README 0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理解 java泛型程序设计 的 通配符类型+通配符的超类型限定 的知识: [1]通配符类型相关 1. ...

  2. java 泛型参数具体类型获取、泛型返回具体类型获取

    自从java支持泛型后,现在,spring生态中的框架及目前的应用都使用了泛型.有的框架如mybatis和spring都需要反射获取类型,以使得序列化和反序列化得以实现,但有时候我们根据项目的需要获取 ...

  3. Java 泛型的本质——类型擦除

    文章目录 简介 Java泛型的类型擦除的证明例子 类型擦除到边界 擦除的代价与使命 使用泛型不是强制的 泛型代码边界的动作 非泛型类库和泛型类库:字节码一模一样 擦除的补偿 泛型与工厂模式 泛型数组 ...

  4. java 泛型参数的类型_Java获得泛型参数类型

    在Android开发中,使用Gson将json字符串转换为Java对象尤为常见.在这个转换过程中,通常会结合泛型参数.接口或者抽象类来封装处理. T t = new Gson().fromJson(r ...

  5. Java 泛型获取实体类型

    学习了动态初始化类,如果参数是各种类型的,要如何处理呢? 这时候,需要用到泛型,而传的数据是实体类型,如果从泛型中获取实体类型呢? 需要使用反射,获得指定类的父类的泛型参数的实际类型,直接上代码 ge ...

  6. Java泛型总结---基本用法,类型限定,通配符,类型擦除

    一.基本概念和用法 在Java语言处于还没有出现泛型的版本时,只能通过Object是所有类型的父类和类型强制转换两个特点的配合来实现类型泛化.例如在哈希表的存取中,JDK1.5之前使用HashMap的 ...

  7. java泛型实例化_java基础-泛型举例详解

    泛型 泛型是JDK5.0增加的新特性,泛型的本质是参数化类型,即所操作的数据类型被指定为一个参数.这种类型参数可以在类.接口.和方法的创建中,分别被称为泛型类.泛型接口.泛型方法. 一.认识泛型 在没 ...

  8. 用了这么多年的 Java 泛型,你对它到底有多了解?|原创

    作为一个 Java 程序员,日常编程早就离不开泛型.泛型自从 JDK1.5 引进之后,真的非常提高生产力.一个简单的泛型 T,寥寥几行代码, 就可以让我们在使用过程中动态替换成任何想要的类型,再也不用 ...

  9. java 泛型 恶心_Java的泛型原来这样让人不舒服

    Type erasure Java泛型中的类型擦除,意为只在编译时刻进行类型检查,实际在运行时,编译器会自动插入相应的转换(cast)代码. List list = new ArrayList(); ...

最新文章

  1. .net 4.0下载
  2. UIProgressView的使用
  3. Zookeeper已经设置了myid文件但是依然报错myid file is missing
  4. CF981E Addition on Segments 线段树分治 + bitset优化
  5. 计算机操作题如何打分,Excel操作题也能自动评分
  6. IDEA Spring环境搭建+简单入门(图文教程)
  7. 分享一个不错的数据分析实战案例【全程附图】EXCEL
  8. 卸载ncurses_linux 安装,卸载 监控服务
  9. 【蜻蜓Dragonfly】client部署
  10. maven deploy jar包和源码包到私服
  11. win7配置maven环境变量
  12. ffmpeg画中画效果
  13. 【OCC学习5】记录最新版本emcc编译occ的bug:opencascade-7.6.0/src/Standard/Standard_Time.hxx:29:25: error: redefinit
  14. Zend Studio 12.5注册码破解
  15. 微信WiFi认证的解决方案
  16. 1小时紧急上线大屏?别怕,你还有即视
  17. 如何在Adobe Reader中存储阅读的Session
  18. Springboot中new出来的实例中含有@Autowired注入时的Spring Bean为NULL
  19. Thread协议介绍
  20. 6-7 十进制转换二进制(15 分)

热门文章

  1. vuejs linux windows,vue.js环境在window和linux安装
  2. 超准中医体质测试 源码_心理测试:这几张心理测试图,一眼看透你的内心!不信你来试试!...
  3. 测试一款CSDN免费下载软件
  4. 2021年春季学期-信号与系统-第四次作业参考答案-第八小题
  5. 无线信标功能初步测试
  6. c++两个vector合并_这才是真正的 Git:分支合并
  7. armv8 汇编 绝对地址赋值_ARMv8带来的变化
  8. win10怎么设置开机启动项目_苹果mac开机启动项怎么设置
  9. centos linux引导修复_CentOS没了,Linux的新世界来了
  10. 西安交通大学2019计算机复试方案,西安交通大学2019年招收硕士研究生复试体检通知...