Java泛型(Generics)
topic:
- 什么是泛型?
- 泛型类、借口
- 泛型方法
- 泛型通配符
- 类型擦除
- 泛型和数组
- 泛型和反射
泛型出现的背景
Java推出泛型以前,程序员可以构建一个元素类型为Object的集合,该集合能够存储任意的数据类型对象,而在使用该集合的过程中,需要程序员明确知道存储每个元素的数据类型。否则很容易发生ClassCastException异常
不使用泛型,易发生ClassCastException
package com.luoqian;
import java.util.ArrayList;
public class GenericsTest {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
// public boolean add(E e)
arrayList.add("java");
arrayList.add(123);
for (int i = 0; i <arrayList.size() ; i++) {
Object o = arrayList.get(i);
// Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
String str = (String)o;
System.out.println(str);
}
}
}
泛型的概念
- JDK5 引入的新特性之一
- 泛型提供了编译时类型安全检测机制,允许我们在编译时检测到非法的类型数据
- 泛型的本质就是参数化类型,也就是所操作的数据类型被指定为一个参数
- 类型安全,消除了数据类型转换
演示代码
// 使用泛型
ArrayList<String> stringArrayList = new ArrayList<>();
stringArrayList.add("123");
stringArrayList.add("456");
stringArrayList.add("789");
for (int i = 0; i <stringArrayList.size() ; i++) {
String s = stringArrayList.get(i);
System.out.println(s);
}
System.out.println("=============");
// 使用泛型
ArrayList<Integer> integerArrayList = new ArrayList<>();
integerArrayList.add(1);
integerArrayList.add(2);
integerArrayList.add(3);
for (int i = 0; i <stringArrayList.size() ; i++) {
Integer integer = integerArrayList.get(i);
System.out.println(integer);
}
泛型类、接口
泛型类的定义语法
class 类名称<泛型标识>{
private 泛型标识 变量名;
}
// 常用的泛型标识:T、E、K、V
泛型类的定义
package com.luoqian;
/**
* 泛型类的定义
* @param <T> 泛型标识 : 类型形参
* T 创建对象时 指定具体的数据类型
*/
public class Generics <T>{
private T data;
public Generics(T data) {
this.data = data;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "Generics{" +
"data=" + data +
'}';
}
}
泛型类的使用语法
//类名<具体的数据类型> 对象名 = new 类名<具体的数据类型>();
//jdk 1.7以后,后面的<>中的具体的数据类型可以省略不写
//类名<具体的数据类型> 对象名 = new 类名<>();
泛型类的测试
package com.luoqian;
public class GenericsMain {
public static void main(String[] args) {
// 泛型类在创建对象时,需要来指定具体的操作数据类型
Generics<String> stringGenerics = new Generics<>("abc");
String data = stringGenerics.getData();
System.out.println(data);
System.out.println("-----------------------");
Generics<Integer> integerGenerics = new Generics<>(123);
Integer data1 = integerGenerics.getData();
System.out.println(data1);
System.out.println("-----------------------");
// 泛型类在创建对象的时候,没有指定类型,将按照Object类型来处理
Generics generics = new Generics("ABC");
Object data2 = generics.getData();
System.out.println(data2);
//泛型类的 泛型标识,只能是引用类型,不支持基本数据类型
//Generics<int> generics1 = new Generics<int>(); // error
System.out.println("-----------------------");
//同一泛型类,根据不同的数据类型创建的对象,本质上是指向同一类型。
System.out.println(stringGenerics.getClass());
System.out.println(integerGenerics.getClass());
System.out.println(stringGenerics.getClass() == integerGenerics.getClass());// true
}
}
![image-20220606170915991](/Users/luoqian/Library/Application%20Support/typora-user-images/image-20220606170915991.png)
泛型类的注意事项
- 泛型类在创建对象的时候,没有指定类型,将按照Object类型来处理
- 泛型类的 泛型标识,只能是引用类型,不支持基本数据类型
- 泛型类型在逻辑上可以看成是多个不同的类型,但实际上都是相同类型(同一泛型类,根据不同的数据类型创建的对象,本质上是指向同一类型。)
泛型类使用案例演示
package com.luoqian.demo02;
import java.util.ArrayList;
import java.util.Random;
/**
* 抽奖机
* @param <T> 现金、物品 不一
*/
public class AwardGetter<T>{
Random random = new Random();
private T item;
//奖品池
ArrayList<T> itemList = new ArrayList<>();
//向奖品池中加入奖品
public void addItems(T item){
itemList.add(item);
}
//获取奖品
public T getAward(){
return itemList.get(random.nextInt(itemList.size()));
}
}
package com.luoqian.demo02;
// 抽奖环节
public class LuckyDraw {
public static void main(String[] args) {
//抽奖机
AwardGetter<String> stringAwardGetter = new AwardGetter<>();
String[] items = {"iphone 13 pro","macbook pro 2021","airpods 3","apple watch"};
for (int i = 0; i < items.length; i++) {
stringAwardGetter.addItems(items[i]);
}
String award = stringAwardGetter.getAward();
System.out.println("congratulation!u get:"+ award);
System.out.println("---------");
//抽奖机
AwardGetter<Integer> integerAwardGetter = new AwardGetter<>();
int[] items2 = {10000,5000,2000,1000,500};
for (int i = 0; i < items2.length; i++) {
integerAwardGetter.addItems(items2[i]);
}
Integer award2 = integerAwardGetter.getAward();
System.out.println("congratulation!u get cash:"+ award2);
}
}å
演示结果:
今日语录
你不需要很厉害才能开始,但你需要开始才能很厉害。