JDK1.5之后出现的新技术泛型(Generic),此技术的最大特点是类中的属性的类型可以由外部决定,泛型即“参数化类型”,一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参,那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式,然后在调用时传入具体的类型(类型实参)
在泛型接口中、泛型类和泛型方法的定义过程中,我们常见的如
T
、E
、K
、V
等形式的参数常用于表示泛型形参,由于接受来自外部,使用时传入的类型实参,从编码的角度也称为参数化类型了。
interface Test
泛型接口{}
public class Test
泛型类{}
public
泛型方法void Test(T data){}
自定义泛型类
public class Node<T> {
private T data;
public Node() {
}
public Node(T data) {
this.data = data;
}
public void print() {
System.out.println(data);
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
使用泛型类
public class TestCode03 {
public static void main(String[] args) {
Node<Integer> integerNode = new Node<>();
integerNode.setData(12);
integerNode.print();
Node<String> stringNode=new Node<>();
stringNode.setData("hello java!");
stringNode.print();
}
}
泛型只是作用于代码的编译阶段,在编译过程中,对于正确检验泛型结果后,会将泛型的相关信息擦除,也就是说,成功编译后的class文件中是不包含任何泛型信息的,泛型信息不会进入到运行时阶段。
使用通配符可以引用其他各种参数化类型,通配符定义的变量主要用作引用,可以调用与参数无关的方法,不能调用与参数有关的方法。
“?” 表示的是可以接受任意的泛型类型,但是只是接受输出,不能修改
public class TestCode03 {
public static void main(String[] args) {
Node<Integer> integerNode = new Node<>(12);
Node<String> stringNode = new Node<>("java");
getDate(integerNode);
getDate(stringNode);
}
public static void getDate(Node<?> node) {
System.out.println("data:" + node.getData());
}
}
就是指一个的操作泛型最大的操作父类,例如:现在最大的上限设置成
Number
类型,那么此时,所能够收到的类型只能是Number
及其子类(Integer
)
public static void getUpperNumberData(Node<? extends Number> node){
//只能是Number类及其子类
System.out.println("data:" + node.getData());
}
泛型下限
泛型下限是指只能设置其具体的类或者父类
public static void getSuperData(Node<? super Integer> node){
//只能设置其具体的类或者父类
System.out.println("data:" + node.getData());
}
泛型除了在类中定义之外,还可以在方法上定义,而且方法上使用泛型,此方法所在的类不一定是泛型的操作类。
定义一个方法,实现任意数组中的两个位置值的交换
import java.util.Arrays;
public class TestCode03 {
public static void main(String[] args) {
//字符串类型数组
String[] str1 = {"javase", "javaee", "javame"};
System.out.println("交换前:" + Arrays.toString(str1));
String[] str2 = swap(str1, 0, 1);
System.out.println("交换后:" + Arrays.toString(str2));
//Integer类型数组
Integer[] arr1 = {1, 2, 3, 4};
System.out.println("交换前:" + Arrays.toString(arr1));
Integer[] arr2 = swap(arr1, 1, 2);
System.out.println("交换后:" + Arrays.toString(arr2));
}
public static <T> T[] swap(T[] arr, int a, int b) {
//交换
T t = arr[a];
arr[a] = arr[b];
arr[b] = t;
//返回数组
return arr;
}
}
在使用集合的时候,我们可以这样向集合中添加指定类型,指定的类型还可以泛型
ArrayList
;> list = new ArrayList<>() list
只能添加Node
类型。
import java.util.*;
public class TestCode03 {
public static void main(String[] args) {
//list只能添加Node类型
ArrayList<Node<String>> list = new ArrayList<>();
Node<String> node1 = new Node<>("hello");
Node<String> node2 = new Node<>("world");
Node<String> node3 = new Node<>("java");
list.add(node1);
list.add(node2);
list.add(node3);
for (Node node : list) {
System.out.println(node.getData());
}
}
}