关于java泛型的使用方式。。。。
转自:http://onewebsql.com/blog/generics-extends-super
以下基本够用了
Today we continue our mini-series on Java Generics. In previous posts we have investigated
- how to crash your IDE using Java wildcards,
- what beginners find surprising when creating parametrized objects, and
- what is the difference between Java arrays and generic lists.
Java type parameters are used as type placeholders.
|
1
|
public class List<X> { } |
A List<X> is a container for X objects, and X can be instantiated with any class: you can haveList<Object>, List<String>, and List<Number>.
Introducing bounds: extends
You often want to restrict the set of types that can be used in instantiation. If you create a class Garage, you want it to hold only Vehicle objects.
The syntax you use in Java is like this:
|
1
|
public class Garage<X extends Vehicle> { } |
Every time you instantiate the Garage, the type parameter has to be a subclass of Vehicle.
|
1
2
3
|
class Car extends Vehicle { }class Motorcycle extends Vehicle { }class Fruit extends Object { } |
Thus Garage<Car> and Garage<Motorcycle> are OK but Garage<Fruit> is not OK.
You can specify more than one bound with extends:
|
1
2
3
4
|
class Vehicle { }interface PassengerVehicle { }interface MotorVehicle { }class ParkingGarage<X extends Vehicle & MotorVehicle & PassengerVehicle> |
You can specify at most one class in the bound (obviously, as you can only inherit from one class in Java) and as many interfaces as you want.
The bound can refer to the typing parameter:
|
1
|
class BST<X extends Comparable<X>> {} |
BST class can only be instantiated with classes X which implement the Comparable<X>interface.
Bounds in method parameters
Java method can be parametrized, too. The syntax is as follows:
|
1
|
<T> T getRandomElement(List<T> list) {} |
As with class definitions, you often want to restrict the type parameter in the method. A method which takes a list of Vehicles and returns the fastest vehicle in the list can have the following type.
|
1
|
<T extends Vehicle> T getFastest(List<T> list) { } |
You can pass as argument a list of any vehicles. List<Car> is OK, List<Motorcycle> is OK, List<Vehicle> is OK, too. List<Number> is not OK.
Note that the following declaration wouldn't do the trick.
|
1
|
Vehicle getFastest2(List<Vehicle> list) { } |
The argument to the method getFastest2 has to be exactly a List<Vehicle>, and not aList<Car>, because List<Car> is not a subtype of List<Vehicle>,
Wilcards
Take a look at the following declaration.
|
1
|
<T extends Vehicle> int totalFuel(List<T> list) { } |
The parameter T occurs only once in the method signature, in an argument. You can imagine that the method body does not use the name T either. In this case you can use an alternative syntax, called wildcards, denoted with ?:
|
1
|
int totalFuel(List<? extends Vehicle> list) { } |
The two signatures for totalFuel are equivalent. The meaning of <? extends Vehicle> is: I don't care what the type parameter is, as long as it is a subclass of Vehicle.
Introducing bounds: super
There is also dual bound, called super. As you guess it is used to denote that you can pass only superclasses of the bound. There are some differences between extends and super, though.
You can't use super in class declaration
The super bound is not allowed in class definition.
|
1
2
|
//this code does not compile !class Forbidden<X super Vehicle> { } |
Why? Because such construction doesn't make sense. For example, you can't erase the type parameter with Vehicle because the class Forbidden could be instantiated with Object. So you have to erase type parameters to Object anyway. If think about class Forbidden<Object>, it can take any value in place of X, not only superclasses of Vehicle. There's no point in using super bound, it wouldn't get us anything. Thus it is not allowed.
Wildcards
The syntax for wildcards is also similar to extends:
|
1
|
int totalValue(Valuer<? super Vehicle> valuer) |
The method has to take a comparator which is able to compare Vehicles. If it comparesObjects as well, that's fine too.
When to use extends and super
Wildcards are most useful in method parameters. They allow for the necessary flexibility in method interfaces.
People are often confused when to use extends and when to use super bounds. The rule of thumb is the get-put principle. If you get something from a parametrized container, useextends.
|
1
2
3
4
5
6
7
|
int totalFuel(List<? extends Vehicle> list) { int total = 0; for(Vehicle v : list) { total += v.getFuel(); } return total;} |
The method totalFuel gets Vehicles from the list, asks them about how much fuel they have, and computes the total.
If you put objects into a parametrized container, use super.
|
1
2
3
4
5
6
7
|
int totalValue(Valuer<? super Vehicle> valuer) { int total = 0; for(Vehicle v : vehicles) { total += valuer.evaluate(v); } return total;} |
The method totalValue puts Vehicles into the Valuer.
It's useful to know that extends bound is much more common than super.
One more tip: if you are intimidated by wildcards (which is natural in the beginning), try to write the explicitly parametrized version first. In typical usage the two versions are equivalent. Eventually, you'll figure out when you can get rid of type parameters and use wildcards.
关于java泛型的使用方式。。。。的更多相关文章
- 用了这么多年的 Java 泛型,你对它到底有多了解?
作为一个 Java 程序员,日常编程早就离不开泛型.泛型自从 JDK1.5 引进之后,真的非常提高生产力.一个简单的泛型 T,寥寥几行代码, 就可以让我们在使用过程中动态替换成任何想要的类型,再也不用 ...
- Java泛型学习---第二篇
泛型学习第一篇 1.泛型之擦拭法 泛型是一种类似"模板代码"的技术,不同语言的泛型实现方式不一定相同. Java语言的泛型实现方式是擦拭法(Type Erasure). 所谓擦拭法 ...
- Java中泛型的详细解析,深入分析泛型的使用方式
泛型的基本概念 泛型: 参数化类型 参数: 定义方法时有形参 调用方法时传递实参 参数化类型: 将类型由原来的具体的类型参数化,类似方法中的变量参数 类型定义成参数形式, 可以称为类型形参 在使用或者 ...
- java泛型基础
泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 这种参数类型可以用在类.接口和方法的创建中, 分别称为泛型类.泛型接口.泛型方法. Ja ...
- 使用java泛型设计通用方法
泛型是Java SE 1.5的新特性, 泛型的本质是参数化类型, 也就是说所操作的数据类型被指定为一个参数. 因此我们可以利用泛型和反射来设计一些通用方法. 现在有2张表, 一张user表和一张stu ...
- Java泛型
什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个 ...
- 初识java泛型
1 协变数组类型(covariant array type) 数组的协变性: if A IS-A B then A[] IS-A B[] 也就是说,java中的数组兼容,一个类型的数组兼容他的子类类型 ...
- 【Java心得总结四】Java泛型下——万恶的擦除
一.万恶的擦除 我在自己总结的[Java心得总结三]Java泛型上——初识泛型这篇博文中提到了Java中对泛型擦除的问题,考虑下面代码: import java.util.*; public clas ...
- Java深度历险(五)——Java泛型
作者 成富 发布于 2011年3月3日 | 注意:QCon全球软件开发大会(北京)2016年4月21-23日,了解更多详情!17 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件 ...
随机推荐
- mysql server查询客户端连接数
SELECT substring_index(HOST, ) AS host_name, state, count(*) FROM information_schema. PROCESSLIST GR ...
- 玩转X-CTR100 l STM32F4 l ADC 模拟数字转换
我造轮子,你造车,创客一起造起来!塔克创新资讯[塔克社区 www.xtark.cn ][塔克博客 www.cnblogs.com/xtark/ ] 本文介绍X-CTR100控制器 AD转换接 ...
- ESET Smart Security 6 – 免费60天(SG)
ESS 60天 - 活动消息来自新加坡脸谱https://www.facebook.com/esetsingapore/app_190322544333196IP限制Sg,suiss提供个在线代理ht ...
- WIN-8“内置管理员无法激活此应用”问题
解决办法:在运行中输入:“gpedit.msc”,就会启动组策略编辑器,依次展开“计算机配置”里面的“Windows设置”,然后是“安全设置”,再就是“本地策略”里面的“安全选项”,在右边查找一项策略 ...
- SharePoint Infopath表单服务-PowerShell
1. 激活可浏览的表单模板 Set-SPInfoPathFormsService -AllowUserFormBrowserEnabling $true -AllowUserFormBrowserRe ...
- CMMI的5个级别
为了帮助软件企业对软件工程过程进行管理和改进,增强开发与改进能力,从而能按时地.不超预算地开发出高质量的软件,美国国防部与卡内基-梅隆大学和美国国防工业协会共同开发和研制了CMMI(软件能力成熟度模型 ...
- Java实现哈夫曼编码和解码
最近无意中想到关于api返回值加密的问题,譬如我们的api需要返回一些比较敏感或者重要不想让截获者得到的信息,像如果是做原创图文的,文章明文返回的话则有可能被抓包者窃取. 关于请求时加密的方式比较多, ...
- C语言基础:函数指针 分类: iOS学习 c语言基础 2015-06-10 21:55 15人阅读 评论(0) 收藏
函数指针:指向函数的指针变量. 函数名相当于首地址. 函数指针定义:返回值类型 (*函数指针变量名)(参数类型1,参数类型2,....)=初始值 函数指针类型:返回值类型 (*)(参数类型1,参数 ...
- 在MNIST数据集,实现多个功能的tensorflow程序
使用带指数衰减的学习率的设置.使用正则化来避免过拟合,使用滑动平均模型使得最终模型更加健壮. import tensorflow as tf from tensorflow.examples.tuto ...
- CentOS使用安装光盘建立本地软件源
本实验的目的是使用CentOS的两张DVD安装光盘作为本地软件源,避免执行yum安装命令时每次都要从网络重新下载. 安装createrepo软件包 createrepo是制作软件源所需要的一个工具,默 ...