Java中Generics的使用
1.Java的Generics与C++的Template
由于Java的Generics设计在C++的Template之后,因此Java的Generics设计吸取Template的很多经验和教训。首先,与Template不同的是,Generics的声明是需要进行类型检查的,而Template不提供这一功能,这使得Generics的使用更加安全。另外,Java的Generics程序只需要编译一次,以后所有程序就可以复用这个类字节码,而Template的实现是为每一个使用Template变量编译成一个新类,这会引起一定的冗余代码。
2.Generics的定义:
2.1类和接口定义
以下是最简单的Generics类定义,定义了一个参数化类型T1:
interface MyList<T1> {….. }
以下是支持多个参数化类型的接口:
interface MyList<T1,T2,T3> {….. }
Java支持带有限制的参数化类型。在下面的例子中,T1的类型必须实现类Comparable接口,T2类型必须为Component类的子类。
interface MyList<T1 implements Comparable, T2 extends Component> {}
复杂的定义可以带有限定的声明,甚至可以使用向前引用。
class Test<A implements ConvertibleTo<B>, B implements ConvertibleTo<A>{}
对于class的定义,基本与interface相同,此处不再详述。
2.2 方法的定义
在方法中,通过定义参数化类型,可以提高方法的抽象级别,提高其可复用性。方法的参数化类型列表放在方法修饰符的后面,返回值的前面。如:
public static <Elem> void swap(Elem[] a,int i,int j)
Elem temp=a[i];
a[i]=a[j]
a[j]=temp;
}
2.3 实际例子
一但Java语言支持了Generics,Collection中的大部分类将用Generics方式重写。例:使用Generics重写的Hashtable的定义
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, java.lang.Cloneable, java.io.Serializable {
public V put(K key, V value) {……}
…….
}
与以前的Hashtable定义不同的是,它增加了两个用于表达Key和Value参数化类型(K,V),由于Dictionary和Map都将支持Generics,因此它们都使用Generics的表达方式。
3.Generics的使用:
3.1 创建对象
Generics类在使用之前,必须按照定义进行初始化,设置参数化类型的实际类型,以下是构造Hashtable和Vector的一些例子。
Hashtable<Integer,String> ht1=new Hashtable<Integer,String>();
Hashtable<Integer,String> ht2=null;
Vector<String> v1=new Vector<String>();
Vector<Integer> v2=new Vector<Integ
3.2 Generics对象的类
在上例中,对于v1和v2对象来说,它们都是Vector类的对象,它们有相同的Class类型,换句话说,在运行时,以下表达式为真。虽然它们使用不同的参数类型创建,但是它们的Class类型是相同的。 Assert(V1.getClass().equals(v2.getClass()));
但是,如果我们定义一个 带有Vector参数的方法,在调用该方法时,传入一个Vector的对象,这将会导致编译失败。这是因为在编译时,这两个对象被当作不同的类型。
void method(Vector<String> v) {};
…
Vector<Integer> v2=new Vector<Integer>();
method(v2);//编译失败
3.3 类的强制转换
对于Generics类的强制转化的原理,我们可以使用通用的转化规则进行操作。需要注意的一点是,同一个Generics类所定义的不同参数化类型的对象之间是不能进行转化的。例如Vector和Vector之间就是不能转化的。另外,Object也不能够转化成Generics类型,但是Generics类可以转化成Object。
以下是一些转化的例子
Class Dictionary<A,B> extends Object{}
Class Hashtable<A,B> extends Dictionary<A,B> {}
Dictionary<String,Integer> d=new Dictionary<String,Integer>();
Hashtable<String,Integer> h=new Hashtable <String,Integer>();
Hashtable<Float,Double> hfd=new Hashtable<Float,Double>();
Object o=new Object();
1) d= (Dictionary<String,Integer>)h//编译成功,运行成功;它们具有父子类关系。
2) h=(Hashtable<String,Integer>)d;// 编译成功,运行失败;它们具有父子类关系。
3) h=(Hashtable<String,Integer>)o;//编译失败,Object不能转化成Generics类;
4) hfd=(Hashtable<Float,Double>)d;//编译失败;
Java中Generics的使用的更多相关文章
- [JavaCore]JAVA中的泛型
JAVA中的泛型 [更新总结] 泛型就是定义在类里面的一个类型,这个类型在编写类的时候是不确定的,而在初始化对象时,必须确定该类型:这个类型可以在一个在里定义多个:在一旦使用某种类型,在类方法中,那么 ...
- Java 中的泛型详解-Java编程思想
Java中的泛型参考了C++的模板,Java的界限是Java泛型的局限. 2.简单泛型 促成泛型出现最引人注目的一个原因就是为了创造容器类. 首先看一个只能持有单个对象的类,这个类可以明确指定其持有的 ...
- Java中Lambda表达式的使用
简介(译者注:虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能.本人建议不要乱用,因 ...
- Java 中泛型的全面解析(转)
Java泛型(generics) 是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter).声明的类型参数在使用时用具体的类型来替换.泛型最主要的应用是在J ...
- Lambda 表达式,Java中应用Lambda 表达式
一.Lambda 表达式 简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数. 链接:知乎 先举一个普通的 Python 例 ...
- Java中Lambda表达式的使用(转)
https://www.cnblogs.com/franson-2016/p/5593080.html 简介(译者注:虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖" ...
- Q:java中的泛型数组
对于java,其是不支持直接创建泛型数组的.当采用如下的方式去创建一个泛型数组时,其会出现错误,编译无法通过的情况. package other.jdk1_5; /** * 该类用于演示泛型数组的创 ...
- java中的泛型1
1.泛型概述 泛型,即“参数化类型”.一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参.那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数 ...
- Java数据结构与算法分析-第一章(引论)-Java中的范型<T,E>构件
一.为什么需要使用范型? 官方的说法是:Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质 ...
随机推荐
- [转]利用C#自带组件强壮程序日志
利用C#自带组件强壮程序日志 在项目正式上线后,如果出现错误,异常,崩溃等情况 我们往往第一想到的事就是查看日志 所以日志对于一个系统的维护是非常重要的 声明 正文中的代码只是一个栗子,一个非常简 ...
- javascript中有关this的解析题
1.作用域链 作用域:浏览器给js一个生存环境(栈)内存 作用域链:js中的关键字var function 都可以提前声明和定义,提前声明和定义,放在我们的内存地址(堆)内存中,然后js从上到下逐行执 ...
- django从请求到响应的过程深入讲解
django启动 我们在启动一个django项目的时候,无论你是在命令行执行还是在pycharm直接点击运行,其实都是执行'runserver'的操作,而ruserver是使用django自带的的we ...
- selenium+python自动化91-unittest多线程生成报告(BeautifulReport)
前言 selenium多线程跑用例,这个前面一篇已经解决了,如何生成一个测试报告这个是难点,刚好在github上有个大神分享了BeautifulReport,完美的结合起来,就能生成报告了. 环境必备 ...
- python post提交数据
使用utf8编码,value是上传的值 1.上传经纬度等数据http://112.74.44.47/VehicleWeb/Acceleration?gps=gpsValue&accelera ...
- Mysql 开启Federated引擎以及使用
FEDERATED是其中一个专门针对远程数据库的实现.但通过FEDERATED引擎创建的表只是在本地有表定义文件,数据文件则存在于远程数据库中通过这个引擎可以实现类似Oracle 下DBLINK的远程 ...
- NLP—WordNet——词与词之间的最小距离
WordNet,是由Princeton 大学的心理学家,语言学家和计算机工程师联合设计的一种基于认知语言学的英语词典.它不是光把单词以字母顺序排列,而且按照单词的意义组成一个“单词的网络”.我们这次的 ...
- 使用three.js开发3d地图初探
three是图形引擎,而web二维三维地图都是基于图形引擎的,所以拿three来开发需求简单的三维地图应用是没什么问题的. 1.坐标转换 实际地理坐标为经度.纬度.高度,而three.js使用的是右手 ...
- JAVA WebSocKet ( 简单的聊天室 )
1, 前端代码 登入页 -> login.html <!DOCTYPE html> <html> <head> <meta charset=" ...
- leetcode973
public class POINT { public int X; public int Y; public int Z; } public class Solution { public int[ ...