Atitit 泛型的知识点
目录
4.1. 提高代码的重用性 主要理由 提升重用性 类型无关 3
- 为什么需要泛型 why
,类型安全
由于忘记了之前在list中也加入了Integer类型的值或其他原因,运行时会出现java.lang.ClassCastException异常。为了解决这个问题,泛型应运而生
2.泛型的使用
Java泛型编程是JDK1.5版本后引入的。泛型让编程人员能够使用类型抽象,通常用于集合里面。
- 定义分类 what
- 编辑类型参数
泛型的定义主要有以下两种:
2.在程序编码中一些包含参数的类。其参数可以代表类或对象等等。(人们大多把这称作模板)不论使用哪个定义,泛型的参数在真正使用泛型时都必须作出指明。
一些强类型编程语言支持泛型,其主要目的是加强类型安全及减少类转换的次数,但一些支持泛型的编程语言只能达到部分目的。
泛型与具体类型 ,类型的类型 占位符
泛型是具有占位符(类型参数)的类、结构、接口和方法,这些占位符是类、结构、接口和方法所存储或使用的一个或多个类型的占位符
。模板的精神其实很简单:参数化类型。换句话说,把一个原本特定于某个类型的算法或类当中的类型信息抽掉,抽出来做成模板参数T。
C#泛型代码在被编译为IL代码和无数据时,采用特殊的占位符来表示泛型类型,并用专有的IL指令支持泛型操作。而真正的泛型实例化工作以"on-demand"的方式,发生在JIT编译时。
1. 第一轮编译时,编译器只为Stack<T>(栈算法)类型产生“泛型版”的IL代码与元数据-----并不进行泛型类型的实例化,T在中间只充当占位符
2. JIT编译时,当JIT编译器第一次遇到Stack<int>时,将用int替换“泛型版”IL代码与元数据中的T---进行泛型类型的实例化。CLR为所有类型参数为“引用类型”的泛型类型产生同一份代码;但如果类型参数为“值类型”,对每一个不同的“值类型”,CLR将为其产生一份独立的代码。
泛型是 的一个新增加的特性,它为使用 语言编写面向对象程序增加了极大的效力和灵活性。不会强行对值类型进行装箱和拆箱,或对引用类型进行向下强制类型转换,所以性能得到提高。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设,所以泛型提高了程序的类型安全。它允许程序员将一个实际的数据类型的规约延迟至泛型的实例被创建时才确定。泛型为开发者提供了一种高性能的编程方式,能够提高代码的重用性,并允许开发者编写非常优雅的解决方案。
泛型类和泛型方法同时具备可重用性、类型安全和效率,这是非泛型类和非泛型方法无法具备的。泛型通常用与集合以及作用于集合的方法一起使用。 版类库提供一个新的命名空间 ,其中包含几个新的基于泛型的集合类。建议面向 2.0 版的所有应用程序都使用新的泛型集合类,而不要使用旧的非泛型集合类,如 ArrayList。有关更多信息,请参见 类库中的泛型 编程指南)。
通过知道使用泛型定义的变量的类型限制,编译器可以更有效地提高Java程序的类型安全。
消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。所有的强制转换都是自动和隐式的。
。另外,一提到泛型,相信大家用到最多的就是在集合中,其实,在实际的编程过程中,自己可以使用泛型去简化开发,且能很好的保证代码质量
泛型编程(Generic Programming)最初提出时的动机很简单直接:发明一种语言机制,能够帮助实现一个通用的标准容器库。所谓通用的标准容器库,就是要能够做到,比如用一个List类存放所有可能类型的对象这样的事;泛型编程让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。泛型即是指具有在多种数据类型上皆可操作的含意,与模板有些相似。STL巨大,而且可以扩充,它包含很多计算机基本算法和数据结构,而且将算法与数据结构完全分离,其中算法是泛型的,不与任何特定数据结构或对象类型系在一起。
泛型编程最初诞生于C++中,由Alexander Stepanov[2]和David Musser[3]创立。目的是为了实现C++的STL(标准模板库)。其语言支持机制就是模板(Templates)。模板的精神其实很简单:参数化类型。换句话说,把一个原本特定于某个类型的算法或类当中的类型信息抽掉,抽出来做成模板参数T。比如qsort泛化之后就变成了:
泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法
泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口。最典型的就是各种容器类,如:List、Set、Map。
泛型类的最基本写法(这么看可能会有点晕,会在下面的例子中详解):
class 类名称 <泛型标识:可以随便写任意标识号,标识指定的泛型的类型>{
private 泛型标识 /*(成员变量类型)*/ var;
.....
}
}
泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中,可以看一个例子:
//定义一个泛型接口public interface Generator<T> {
public T next();
}
当实现泛型接口的类,未传入泛型实参时:
在java中,泛型类的定义非常简单,但是泛型方法就比较复杂了。
尤其是我们见到的大多数泛型类中的成员方法也都使用了泛型,有的甚至泛型类中也包含着泛型方法,这样在初学者中非常容易将泛型方法理解错了。
泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型
我们知道Ingeter是Number的一个子类,同时在特性章节中我们也验证过Generic<Ingeter>与Generic<Number>实际上是相同的一种基本类型
可以解决当具体类型不确定的时候,这个通配符就是 ? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。
public static <t> void print(t param2 ) {
System.out.println(param2);
}
一个被举了无数次的例子:
List arrayList = new ArrayList();
arrayList.add("aaaa");
arrayList.add(100);
for(int i = 0; i< arrayList.size();i++){
String item = (String)arrayList.get(i);
Log.d("泛型测试","item = " + item);
}
毫无疑问,程序的运行结果会以崩溃结束:
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
ArrayList可以存放任意类型,例子中添加了一个String类型,添加了一个Integer类型,再使用时都以String的方式使用,因此程序崩溃了。为了解决类似这样的问题(在编译阶段就可以解决),泛型应运而生。
我们将第一行声明初始化list的代码更改一下,编译器会在编译阶段就能够帮我们发现类似这样的问题。
List<String> arrayList = new ArrayList<String>();
...//arrayList.add(100); 在编译阶段,编译器就会报错
Java技术----Java泛型详解 - 极客头条 - CSDN.NET.html
Atitit.java 与c#的泛型实现对比.doc
Atitit.泛型类 静态方法 使用引用泛型类型参数.doc
atitit.泛型编程总结最佳实践 vO99 java c++ c#.net php
paip.使用泛型时未能找到类型或命名空间名称“T.txt
paip.泛型 针对泛型创建默认对象.txt
paip.自定义java 泛型类与泛型方法的实现总结.txt
atitit.泛型编程总结最佳实践 vO99 java c++ c#.net php
java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一 - little fat - 博客园.html