目录
- 什么是泛型?
- 使用泛型的缺点和好处
- 以上理解
- 有关泛型的定义和使用
- 泛型集合
- 泛型类
- 泛型方法
- 泛型的高级用法
什么是泛型?
泛型:就是一种不确定的数据类型。
比如:ArrayList<E> ,其中 E 就是泛型。 这种不确定的数据类型需要在使用这个类的时候才能够确定出来。
泛型可以省略,如果省略,默认泛型是Object类型。 参考文献
泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。泛型类是引用类型,是堆对象,主要是引入了类型参数这个概念。
-----百度百科
使用泛型的缺点和好处
在 Java 1.5 之前没有泛型,通常需要使用强制类型转换的方式将一种数据类型转换为另一种数据类型,这种转换要求开发者对实际参数的类型具有可预知性。对于强制类型转换错误的情况,编译器可能不会提示错误,但是在运行时会出现异常,这是一个安全隐患。
为了解决这一隐患,从 Java 1.5 开始提供了泛型。泛型可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。本节将详细介绍 Java 中泛型的使用----C语言中文网
以上理解
我们都知道,在不使用泛型去定义方法、类、接口集合等的时候,都要有确定的数据类型,即int类型、String类型等等,如果输出或输入不符合已定义的数据类型,则会报错。所以不管是定义方法、类等的什么都好,都要有明确的、准确的事先定义好数据类型,也即是要 求开发者对实际参数的类型具有可预知性,也许你会想,这样不是很好么,要什么类型的数据,我都定义好了,直接使用就行,但是这样往往不符合开发的代码重用性和便捷性,为什么呢?用下面例子来讲解。
就以方法的定义为例,假如一个show([形式参数类型 形式参数])方法要实现不同类型的参数的传入,不使用泛型的方法来定义的话,是不是有多少种不同类型的形参类型,就要重载多少个不同形参类型的方法?这样你不觉的很麻烦很浪费精力么,一个方法重载两三次还好,要是有N个方法要实现N种不同形参类型的重载呢,难度还一个一个的写出来不成,要是这样,嘿,我想你可以会崩溃的。。。在此,泛型的作用就突显出来了,那么,泛型的工作原理是什么呢(还是以show([形式参数类型 形式参数])方法为例),这其实很简单,就是把形式参数类型当成形式参数来使用,不使形式参数类型固定死,这样,传入的实参是什么类型的数据,定义方法的形式参数类型就是什么数据类型,即是数据类型的“类型参数”,也就是参数化类型。同理,我们把泛型的使用范围扩大,在类、接口、集合等中也是一样的。我们也可以为类、接口、集合或方法指定一个类型参数,通过这个参数限制操作的数据类型,从而保证类型转换的绝对安全。通俗点说,就是固定死了类型参数,传值只能传指定的类型参数,和不使用泛型类似,不过能力大了不少,非泛型时,只能指定一个数据类型,泛型时,可以指定多个数据类型。例如限制List集合只能传入int类型和Student类型的数据,可以这样写Map<int,Student> map;,其中Student是类,这样Map集合就被限制了只能传入int类型的键和Student类型的值,传入其他类型的键或值都会报错。
下面是有关泛型的定义和使用
声明:使用尖括号把标识符括起来,例如: <N>
声明一个以上的类型参数,只需要将类型用逗号隔开即可
常用的标识符有A,C,B,T,P,D等。更详细的声明在下面有讲。
使用方法:比如泛型声明了<N>,则可以在需要的地方使用 N 来表示使用
下面介绍泛型集合、泛型类及泛型方法
泛型集合
声明:List<V> list; 或 Map<K,V> map;
注意:V和K一定要是基础数据类型(String等等)、已声明好的类或者是List/Map包含于方法/类的方法/类已定义好的泛型,不能是包含List/Map的方法/类没有定义好的泛型
(声明)代码说明:
public class test1 {
public void test(){
// 声明List泛型集合,包含List/Map的方法/类没有定义好的泛型
List<dd> list;
}
public static void main(String[] args) {
System.out.println("。。。。系统会报错。。。。");
}
}
public class test2 {
public<N> void test(N a){
System.out.println(a);
// 声明List泛型集合,List/Map包含于方法/类的方法/类已定义好的泛型
List<N> list;
}
public static void main(String[] args) {
System.out.println("。。。。成功。。。。");
}
}
public class test3 {
public<N> void test(){
// 声明List泛型集合,以声明好的类
List<test3 > list;
}
public static void main(String[] args) {
System.out.println("。。。。成功。。。。");
}
}
(使用)代码说明:
public class test4{
public <K> K test(K a){
List<K> list = new ArrayList();
list.add( a );
System.out.println("得到list的数据:"+list.get( 0 ));
return a;
}
public static void main(String[] args) {
test4 test = new test4();
test.test(2019);
System.out.println("数据类型:"+test.test( "hello" ).getClass());
}
}
泛型类
除了可以定义泛型集合之外,还可以直接限定泛型类的类型参数。
语法格式如下:
其中,class_name 表示类的名称,data_ type1 等表示类型参数。Java 泛型支持声明一个以上的类型参数,只需要将类型用逗号隔开即可。public class class_name<data_type1,data_type2,…>{}
泛型类一般用于类中的属性类型不确定的情况下。在声明属性时,使用下面的语句:
- private data_type1 property_name1;
- private data_type2 property_name2;
在实例化泛型类时,需要指明泛型类中的类型参数,并赋予泛型类属性相应类型的值
(声明和使用)代码说明:
public class test1<D>{
private D paramente;
public D test(D a){
this.paramente = a;
return a;
}
public static void main(String[] args) {
test1<Integer> te = new test1();
System.out.println("变量:"+te.test( 2019 )+"\t\t");;
}
}
//
//限制多个类型
public class test1<D,Integer,L>{
private D paramente1;
private Integer paramente2;
private L paramente3;
public D test(D a,Integer b, L c){
this.paramente1 = a;
this.paramente2 = b;
this.paramente3 = c;
System.out.println(this.paramente1+"--"+this.paramente2+"--"+this.paramente3);
return a;
}
}
public class test2 {
public static void main(String[] args) {
test1<String, Integer, Float> te = new test1();
System.out.println("变量:"+te.test( "2019",110 , 2019.0407F)+"\t\t");;
}
}
泛型方法
- 是否拥有泛型方法,与其所在的类是不是泛型没有关系。
- 泛型方法使得该方法能够独立于类而产生变化。如果使用泛型方法可以取代类泛型化,那么就应该只使用泛型方法
- 对一个 static 的方法而言,无法访问泛型类的类型参数。因此,如果 static 方法需要使用泛型能力,就必须使其成为泛型方法。
- 一般来说编写 Java 泛型方法,其返回值类型至少有一个参数类型应该是泛型,而且类型应该是一致的,如果只有返回值类型或参数类型之一使用了泛型,那么这个泛型方法的使用就被限制了。
语法格式如下:
[访问权限修饰符][static][final]<类型参数列表>返回值类型方法名([形式参数列表])
public class test1{
public<D> D test(D a){
System.out.println(a);
return a;
}
public static void main(String[] args) {
test1 te= new test1();
te.test( "hello" );
}
}
//限制类型为test2和Integer
public class test2{
Integer ii;
public<test1,Integer> test2 test(test2 a, Integer d){
this.ii = (java.lang.Integer) d;
System.out.println(a);
return a;
}
public static void main(String[] args) {
test2 te= new test2();
te.test( te , 2019);
te.test( te.ii, 886 );
}
}
扩展之处: