一、概念
泛型其实就是一种参数化的集合,它限制了你添加到集合中的类型,泛型本质就是一种参数化的类型。
二、使用泛型之前产生的问题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.ListDemoException in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integerat 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类型的父类。