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

java 有界类型_java泛型之有界类型

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

package test;

public class Stats {

private T[] nums;

public Stats(T[] o) {

nums = o;

}

public double average() {

double sum = 0d;

for(int i = 0; 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只能被superclass或其子类替代。因此,superclass定义了包括superclass在内的上限。针对上例,我们可以通过将Number指定为上界,修复前面显示的Stats类,示例如下:

package test;

public class Stats {

private T[] nums;

public Stats(T[] o) {

nums = o;

}

public double average() {

double sum = 0d;

for(int i = 0; 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 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 dob = new Stats<>(dnums);

double w = dob.average();

System.out.println("dob average is " + w);

}

}

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

public class Stats {......}

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

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

class Gen {......}

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

相关文章:

  • oracle mysql8_这一刻,MySQL 8终于追赶上了Oracle 8
  • power of three java_【LeetCode】326. Power of Three 3的幂(Easy)(JAVA)
  • python2和pytho3切换_电脑上同时安装Python2和Pytho
  • 学JS对学Java有用吗_【JS】编程语言那么多,为啥学Java的人那么多?
  • java offset用法_Java OffsetTime plusMinutes()用法及代码示例
  • php 判断是否对象_利用PHP判断JSON对象是否存在
  • php链接数据库2000,Linux下PHP连接Microsoft SQL Server 2000(图)
  • java获取内存变量,java – 易失性变量,从主内存刷新/读取
  • java二维函数怎么放到表里,调用函数传递二维数组
  • jsonrpc php使用,基于php的json rpc原理及应用
  • php正则表达式变量替换,js正则表达式replace替换变量方法
  • php ab webbance,Apache的ab工具实例详解
  • 腾讯的PHP框架,腾讯音视频 TRTC
  • php定时刷新token,PHP定时任务获取微信access_token的方法实例分享
  • java机房上机模拟系统,机房上机安排管理系统,基于B/S模式下的JAVA系统
  • php的引用
  • 《Java编程思想》读书笔记-对象导论
  • 08.Android之View事件问题
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • echarts花样作死的坑
  • Laravel核心解读--Facades
  • redis学习笔记(三):列表、集合、有序集合
  • ⭐ Unity 开发bug —— 打包后shader失效或者bug (我这里用Shader做两张图片的合并发现了问题)
  • 彻底搞懂浏览器Event-loop
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 什么软件可以提取视频中的音频制作成手机铃声
  • 手机端车牌号码键盘的vue组件
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 白色的风信子
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • 数据可视化之下发图实践
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #100天计划# 2013年9月29日
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (70min)字节暑假实习二面(已挂)
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (利用IDEA+Maven)定制属于自己的jar包
  • (七)c52学习之旅-中断
  • (十)c52学习之旅-定时器实验
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • .net core开源商城系统源码,支持可视化布局小程序
  • .NET gRPC 和RESTful简单对比
  • .net redis定时_一场由fork引发的超时,让我们重新探讨了Redis的抖动问题
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .net开发引用程序集提示没有强名称的解决办法
  • .NET中的Event与Delegates,从Publisher到Subscriber的衔接!
  • 。Net下Windows服务程序开发疑惑
  • :O)修改linux硬件时间
  • @RunWith注解作用
  • @Transaction注解失效的几种场景(附有示例代码)
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]