Java学习-08-韩顺平老师
Java-泛型
目录:
01-为什么要使用泛型?
02-泛型
03-自定义泛型
04-自定义泛型方法
05-泛型的继承和通配符
为什么要使用泛型?
1.使用传统的方法的缺点:
1.不能对加入集合ArrayList中的数据类型进行约束。
2.遍历的时候,需要进行进行类型转换,如果集合比较大,对效率有影响。
2.使用泛型的好处:
1.编译时,检查添加元素类型,提高安全性。
2.减少类型转换的次数,提高效率。
泛型
基本介绍:
1.泛型又称参数化类型,是JDK5.0出现的新特性,解决数据类型的安全问题。
2.在声明或实例化时,只要指定好需要的具体的类型即可。
3.Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会发生异常,
同时,代码更加简洁,健壮。
4.泛型的作用:可以在类声明时通过一个表示类中某个属性的类型,或者某个
方法的返回值的类型,或者是参数类型。
基本语法:
interface 接口<T> {} 和 class 类<K,V>{}
说明:其中T,K,V不代表值,表示类型。也就是说,泛型是存储数据类型的类型。
实例化代码:
public class generic_ {
public static void main(String[] args) {
ArrayList<String> strings = new ArrayList<>();
strings.add("张三");
// strings.add(100); // 错误,已经指定了集合只能存放String
HashSet<Dog> dogs = new HashSet<>(); // HashSet只能存放Dog数据类型.
Iterator<Dog> iterator = dogs.iterator(); // 自动补全迭代器里存放的是什么类型的数据
}
}
class Dog{
}
注意细节:
1.在指定泛型后具体类型后,可以传入该类型或者其子类型。
2.泛型使用形式
ArrayList<String> strings = new ArrayList<>() (推荐)
ArrayList<String> strings = new ArrayList<String>();
3. List list = new ArrayList(); 如果没有指定,默认泛型就是Object。
自定义泛型
自定义泛型类:
/* 语法
class Dog<T,R..> {
成员
}
*/
class Dog<T>{
private T t; // 使用泛型定义类型
//public static T t; // 错误
// 解释:
// 泛型T的确认实在实例化对象的时候,而静态属性的初始化是在类加载
// 所以不能用泛型来修饰静态成员
public T show(){
return t;
}
}
注意细节:
1.普通成员可以使用泛型。
2.使用泛型的数组,不能初始化。
3.静态方法不能使用类的泛型。
4.泛型类的确定是在创建对象的时候确定的。
5.在创建对象的时候没有指定泛型,默认就是Object。
自定义泛型接口:
/* 语法
interface 接口名<T,R..> {
成员
}
*/
interface Usb <T>{
T show();
}
注意细节:
1.接口中,静态成员不能使用泛型。
2.泛型接口的类型,在继承接口或者实现接口时确定。
3.没有指定类型,默认就是Object。
自定义泛型方法
/* 基本语法
修饰符 <T,R> 返回类型 方法名(参数列表) {
}
*/
class Dog<T> {
T t;
public<R> void cry(R r){ // 自定义泛型方法,参数列表中可以使用定义的泛型
System.out.print(r);
}
public T show(){ // 方式使用了泛型,并不能称为自定义泛型方法
return t;
}
}
注意细节:
1.泛型方法,可以定义在普通类中,也可以定义在泛型类当中。
2.当泛型方法被调用使,类型会确定,调用时直接给定,编译器会自动识别。
3.public void eat(E e) {},修饰符后没有<T,R> eat方法不是泛型方法,
而且使用了类型。
泛型继承和通配符
基本介绍:
1.泛型不具备继承性,如
List<Object> list = new ArrayList<String>() 错误,不能用List<Object>类型接收ArrayList<String>
2.通配符:
1)<?>:支持任意泛型类型。
2)<? extends A>:支持A类及其子类,规定了泛型的上线。
3)<? super A>:支持A类及其父类,不限于直接父类。
代码演示:
public class GenericExercise {
public static void main(String[] args) {
print1(new ArrayList<Object>());//ok
print1(new ArrayList<String>());//ok
print1(new ArrayList<AA>());//ok
print1(new ArrayList<BB>());//ok
print1(new ArrayList<CC>());//ok
// print2(new ArrayList<Object>());// 报错,不是AA的子类
// print2(new ArrayList<String>());//报错 不是AA的子类
print2(new ArrayList<AA>());//ok
print2(new ArrayList<BB>());//ok
print2(new ArrayList<CC>());//ok
print3(new ArrayList<Object>());//ok
// print3(new ArrayList<String>());//报错 不是AA的
print3(new ArrayList<AA>());//ok
// print3(new ArrayList<BB>());//报错 不是AA的父类
// print3(new ArrayList<CC>());//报错 不是AA的父类
}
public static void print1(List<?> AA){
for (Object obj : AA) {
print1((List<?>) obj);
}
}
public static void print2(List<? extends AA> AA){
for (Object obj : AA) {
print1((List<?>) obj);
}
}
public static void print3(List<? super AA> AA){
for (Object obj : AA) {
print1((List<?>) obj);
}
}
}
class AA {}
class BB extends AA {}
class CC extends BB {}