Java泛型类的定义和使用(非常详细)
在 Java 开发中,泛型是一项非常重要的技术。使用泛型技术可以通过类型参数化的方式处理不同类型的对象,同时又能保证编译时的类型安全。在集合中使用泛型,可以省去使用集合数据时要做的类型转换操作。
泛型的本质是参数化类型,是将所操作的数据类型指定为一个参数。
泛型解决了数据类型的安全性问题,在声明类或实例化时需要指定好处理数据的具体类型。这种参数化类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
Java 泛型可以让程序在编译时有更强的类型检查,解决程序在编译时发出的数据类型警告。同时,可以消除强制类型转换,使代码更加简洁、健壮。
接下来,通过案例来演示这种情况:
在定义 MyCls 类时可以使用 <T> 声明参数类型(T 其实就是特定类型的简写字符,这里也可以使用其他字符),然后将 set() 方法的参数类型和 get() 方法的返回值类型都声明为 T。这样在存入元素时,元素的类型就被限定了,容器就被限定只能存入 T 类型的元素。取出元素时,由于元素类型已被限定,因此也无须类型转换。
接下来,通过案例来演示如何自定义泛型:
泛型在定义集合类时,使用“<参数化类型>”的方式指定该集合存储的数据类型,语法格式如下:
了解了泛型的定义和基本使用后,下面进一步了解一下泛型通配符的概念。泛型通配符用符号“?”表示。例如,List<?> 表示可以通配 List<String>、List<Object> 等各种具体泛型 List。
接下来,通过案例来演示泛型通配符的使用:
此外,在方法 show() 的参数声明中,List 参数使用了泛型通配符“?”,所以该方法能接收多种参数类型的集合。
泛型的本质是参数化类型,是将所操作的数据类型指定为一个参数。
泛型解决了数据类型的安全性问题,在声明类或实例化时需要指定好处理数据的具体类型。这种参数化类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。
Java 泛型可以让程序在编译时有更强的类型检查,解决程序在编译时发出的数据类型警告。同时,可以消除强制类型转换,使代码更加简洁、健壮。
Java泛型类的声明和使用
Java 集合默认情况下会自动将添加的数据转为 Object 类型存储,因此取出数据的时候,需要使用 Object 类的变量来接受。另外,因为无法判断取出的数据原本是什么类型的,所以会导致强制类型转换的时候容易出错。接下来,通过案例来演示这种情况:
public class Demo { public static void main(String[] args) { MyCls mycls = new MyCls(); // 创建MyCls对象 mycls.set("字符串"); // 设置字符串类型的数据 Integer i = (Integer) mycls.get(); // 取值时强制转换为Integer类型 System.out.println(i); } } class MyCls { private Object variable; public void set(Object variable) { this.variable = variable; } public Object get() { return variable; } }程序运行会报错,提示“ClassCastException”,中文含义是“类型转换异常”,这是因为第 5 行存入了一个 String 类型的值,而第 6 行取出这个值时,将其强制转换为 Integer 类型,出现了类型转换的错误,为了避免这个错误,此时就可以使用泛型。
在定义 MyCls 类时可以使用 <T> 声明参数类型(T 其实就是特定类型的简写字符,这里也可以使用其他字符),然后将 set() 方法的参数类型和 get() 方法的返回值类型都声明为 T。这样在存入元素时,元素的类型就被限定了,容器就被限定只能存入 T 类型的元素。取出元素时,由于元素类型已被限定,因此也无须类型转换。
接下来,通过案例来演示如何自定义泛型:
public class Demo { public static void main(String[] args) { MyCls<String> mycls = new MyCls<String>(); // 设置字符串类型参数 mycls.set("字符串"); // 设置字符串类型参数 String s = mycls.get(); // 获取字符串类型参数 System.out.println(s); } } class MyCls<T> { // 创建类时,指定泛型类型为T类型 T variable; public void set(T variable) { // 指定set()方法参数为T类型 this.variable = variable; } public T get() { // 指定get()方法返回值为T类型 return variable; } }程序的运行结果如下:
字符串
程序中 MyCls 类声明了泛型类型为 T,其中 set() 方法参数类型和 get() 方法返回值类型都为 T。在 main() 方法中创建 MyCls 对象实例时,通过 <String> 将泛型 T 指定为 String 类型,调用 set() 方法存入 String 类型的数据,调用 get() 方法取出的值自然是 String 类型,这样就不需要进行类型转换,使得程序更加健壮。Java泛型在集合中的使用
在 Java 程序使用集合时,代码中会出现类型安全的警告,其原因是未指定泛型。如果指定了泛型,就不会出现这种警告。泛型在定义集合类时,使用“<参数化类型>”的方式指定该集合存储的数据类型,语法格式如下:
集合类型<参数化类型> 集合变量 = new 集合类型<参数化类型>();接下来,通过案例来演示泛型在集合中的使用:
import java.util.ArrayList; public class Demo { public static void main(String[] args) { // 创建泛型集合,限定只能添加整型数据 ArrayList<Integer> list = new ArrayList<Integer>(); list.add(100); // 添加元素 list.add(200); list.add(300); System.out.println(list); // 打印集合 } }程序的运行结果如下:
[100, 200, 300]
程序中创建集合的时候,指定了泛型为 Integer 类型,限制该集合只能添加 Integer 类型的元素,编译文件时,不再出现类型安全警告,这时如果向集合中添加非 Integer 类型的元素,会出现编译时异常。了解了泛型的定义和基本使用后,下面进一步了解一下泛型通配符的概念。泛型通配符用符号“?”表示。例如,List<?> 表示可以通配 List<String>、List<Object> 等各种具体泛型 List。
接下来,通过案例来演示泛型通配符的使用:
import java.util.*; public class Demo { public static void main(String[] args) { List<?> list = null; // 声明List泛型为? list = new ArrayList<Integer>(); // 编译时异常 // list.add(666); // 编译时异常 list = new ArrayList<String>(); // 编译时异常 // list.add("AAA软件教育"); // 编译时异常 // list.add(null); // 添加元素null System.out.println(list); List<Float> list1 = new ArrayList<Float>(); List<String> list2 = new ArrayList<String>(); list1.add(3.1415926f); list2.add("梅超风"); show(list1); show(list2); } static void show(List<?> list) { for (Object object : list) { System.out.println(object); } } }程序的运行结果如下:
[null]
3.1415925
梅超风
此外,在方法 show() 的参数声明中,List 参数使用了泛型通配符“?”,所以该方法能接收多种参数类型的集合。