java 深入理解泛型
2017-06-14 15:46
323 查看
泛型相信很多人都遇到过,比如使用集合的时候类似List,封装适配器的时候。泛型在处理数据的时候可以帮助我们,只处理指定类型的数据,比如集合无论我们存什么样的数据,取出的时候都会被认为是Object的对象,一般都需要我们去强转为想要的数据类型,这个时候可能会出现类型转换错误。比如:
这样在执行的时候就会出现Integer cannot be cast to String
如果我们指定了泛型,如下
我们指定集合泛型为String,实例化的时候不必重复指定,这个时候在添加Integer类型数据就不能通过了。
正如你所见,泛型的语法格式就是< E >,这里的E就是所谓的参数化类型(和方法的形参一样,不是真实存在的东西)
自定义泛型类或者接口
调用:
这里在定义一个类的时候,使用了泛型
从泛型类派生子类
子类继承时的格式
正确的格式,父类后跟具体类型
和调用方法不同的是,泛型类或者泛型接口,可以不传入形参:
接口也是同样的写法,不在赘述。
并不存在泛型类
运行结果:
也就是说,不管我们为泛型参数传入哪一种类型实参,对于java来说,它们依然被当做一个类来处理,在内存中也只占用一块内存空间,因此在静态方法,静态代码块或者静态变量的声明和初始化中不允许使用泛型,如下:
由于系统并不会产生真正的泛型类,所有instanceof关键字后不能有泛型类,如下:
泛型作为类型参数,可以让我们处理不同的指定类型的数据,但是泛型类、泛型接口是不存在的。
List list=new ArrayList<>(); list.add("你好"); list.add(5); for (Object object : list) { String str=(String) object; System.out.println(str); }
这样在执行的时候就会出现Integer cannot be cast to String
如果我们指定了泛型,如下
List<String> list=new ArrayList<>(); list.add("你好"); //编译不通过 list.add(5);
我们指定集合泛型为String,实例化的时候不必重复指定,这个时候在添加Integer类型数据就不能通过了。
正如你所见,泛型的语法格式就是< E >,这里的E就是所谓的参数化类型(和方法的形参一样,不是真实存在的东西)
自定义泛型类或者接口
public class Pet<T> { public void eat(T t){ System.out.println("吃"+t); } }
调用:
Pet<String> pet=new Pet<>(); pet.eat("s");
这里在定义一个类的时候,使用了泛型
从泛型类派生子类
子类继承时的格式
//继承泛型类的时候,父类不能跟泛型 public class Dog extends Pet<T>{ }
正确的格式,父类后跟具体类型
//继承泛型类的时候,父类跟具体类型 public class Dog extends Pet<String>{ }
和调用方法不同的是,泛型类或者泛型接口,可以不传入形参:
//也可以什么都不写 public class Dog extends Pet{ }
接口也是同样的写法,不在赘述。
并不存在泛型类
List<String> listS=new ArrayList<String>(); List<Integer> listI=new ArrayList<Integer>(); if (listI.getClass()==listS.getClass()) { System.out.println("true"); System.out.println(listI.getClass().getSimpleName()); System.out.println(listS.getClass().getSimpleName()); }else { System.out.println("flase"); System.out.println(listI.getClass().getSimpleName()); System.out.println(listS.getClass().getSimpleName()); }
运行结果:
true ArrayList ArrayList
也就是说,不管我们为泛型参数传入哪一种类型实参,对于java来说,它们依然被当做一个类来处理,在内存中也只占用一块内存空间,因此在静态方法,静态代码块或者静态变量的声明和初始化中不允许使用泛型,如下:
public class Pet<T> { //代码不能通过,不能在声明静态变量时使用泛型 static T info; //可以声明 T info2; public void eat(T t){} //下面代码错误,静态方法中不能使用泛型 public static void play(T t){ //下面代码错误 T a; } }
由于系统并不会产生真正的泛型类,所有instanceof关键字后不能有泛型类,如下:
List<String> listS=new ArrayList<String>(); //编译错误,instanceof关键字后不能有泛型类 if(listS instanceof ArrayList<String>){}
泛型作为类型参数,可以让我们处理不同的指定类型的数据,但是泛型类、泛型接口是不存在的。
相关文章推荐
- java里程碑之泛型--深入理解泛型
- 深入理解Java之泛型
- 深入理解Java与Kotlin的泛型(Generic Type)和型变(Variance)
- Java Reflection深入理解泛型(generics)
- 深入理解 Java 泛型
- java里程碑之泛型--深入理解泛型
- Java 进阶巩固:深入理解 泛型
- 关于Java泛型深入理解小总结
- Java泛型深入理解
- 深入理解Java之泛型
- 深入理解Java之泛型 企
- 深入理解Java之泛型
- Java泛型深入理解
- 关于Java泛型深入理解总结
- 深入理解Java泛型
- 深入理解Java之泛型
- 深入理解Java之泛型
- 深入理解Java之泛型
- 深入理解 Java 泛型
- <转>深入理解 Java 泛型:类型擦除、通配符、运行时参数类型获取