一、概念
泛型其实就是一种参数化的集合,它限制了你添加到集合中的类型,泛型本质就是一种参数化的类型。
二、使用泛型之前产生的问题
package day04;
import java.util.ArrayList;
import java.util.List;
/**
* @author qx
* @date 2023/06/27
* @desc 没有使用泛形的用法
*/
public class ListDemo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add(3);
for (int i = 0; i < list.size(); i++) {
Integer temp = (Integer) list.get(i);
System.out.println(temp);
}
}
}
这个集合并没有指定具体的类型,所以添加了两种类型,字符串和整形,但是在后面数据循环的时候进行了数据转换的操作。
程序执行结果:
"C:\Program Files\Java\jdk1.8.0_351\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2023.1.2\lib\idea_rt.jar=63588:D:\Program Files\JetBrains\IntelliJ IDEA 2023.1.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_351\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\rt.jar;E:\javaProject\MyJava\out\production\MyJava" day04.ListDemo
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at day04.ListDemo.main(ListDemo.java:19)
Process finished with exit code 1
出现了数据转换的异常。因为String类型不能转换成Integer类型。
三、使用泛型
package day04;
import java.util.ArrayList;
import java.util.List;
/**
* @author qx
* @date 2023/06/27
* @desc 没有使用泛形的用法
*/
public class ListDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("hello");
// 使用泛型后 存入其他类型会在编译期间就会报错 大大减少出问题的可能性
list.add(3);
}
}
我们的泛型指定类型为字符串,所以只能存储字符串类型的数据,如果存入其他类型的数据,编译器就会提示报错,大大减少了后面处理数据出问题的可能性。
四、泛型的使用方式
1.泛型表示类
泛型加在类上面,例如:class xx<T>,T可以为任意标识,也可以使用T、E、K、V等参数来表示泛型。
package day04;
/**
* @author qx
* @date 2023/06/27
* @desc 泛型类
*/
public class GenericsTest<T> {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public static void main(String[] args) {
GenericsTest<String> generics = new GenericsTest<>();
generics.setValue("hello");
// 输出hello
System.out.println(generics.getValue());
}
}
2.泛型接口
泛型接口和泛型类的定义和使用基本相同。
package day04;
/**
* @author qx
* @date 2023/06/27
* @desc 泛型接口
*/
public interface Generics<T> {
public T data();
}
3.泛型方法
在方法上使用泛型,一般是指定参数的泛型
类似:访问修饰符 <T> 访问值类型 方法名(T t)
package day04;
/**
* @author qx
* @date 2023/06/27
* @desc 泛型方法
*/
public class GenericsDemo {
public <T> void show(T x) {
System.out.println("输出:" + x.getClass().getTypeName());
}
public static void main(String[] args) {
GenericsDemo genericsDemo = new GenericsDemo();
genericsDemo.show(2);
}
}
程序执行结果:
输出:java.lang.Integer
五、泛型通配符
上界通配符:<? extends ClassType>表示该通配符为ClassType的所有子类型。它表示任何类型都是ClassType类型的子类。
下界通配符:<? super ClassType>表示该通配符为ClassType的所有超类型,它表示是任何类型都是ClassType类型的父类。