-
为什么需要泛型?
- 为了使集合能够记住集合内各元素的类型,且能够达到只要编译时不出现问题,运行就不会出现java.lang.ClassCastException异常——使用泛型
-
什么是泛型
- JDK1.5之后出现了新的技术——泛型(Generic),此技术的最大特点是类中的类型可以由外部决定。泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传实参。那么参数化是指将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)
-
自定义泛型接口、泛型类
-
泛型类和方法的定义:
// 泛型类的定义 Class Node<T> { private T data; public Node() {} public Node(T data) { this.data = data; } public T getData() { return data; } public void setData(T data) { this.data = data; } } // 泛型接口的定义 interface Shopping<T> { public void shopping(T name); }
-
-
通配符
// 问题 Node<Number> c1 = new Node<Number>(); Node<Integer> c2 = new Node<Integer>(); c1 == c2;// 此时无法转换 public static void getData(Node<Number> data) { System.out.ptintln("data=" + data.getData()); }
-
此时可以使用通配符:“?”表示的是可以接收任意的泛型类型,但是只能接收输出,并不能修改。
public static void getData(Node<?> data) { System.out.println("data=" + data.getData()); } // 使用通配符可以引用其他各种参数化类型,通配符定义的变量主要用作引用,可以调用与参数无关的方法,不能调用与参数有关的方法
-
泛型上限就指一个操作泛型最大的操作父类。泛型的上限通过以下语法完成:
// ? extends 类 public static void getUpperNumberData(Node<? extends Number> data) { // 只能是Number类及其子类 System.out.println("data=" + data.getData()); }
-
泛型的下限指的是只能设置其具体的类或父类。设置语法如下:
// ? super 类
-
-
泛型方法
-
泛型除了在类中定义之外,还可以在方法上定义,而且在方法上使用泛型,此方法所在的类不一定是泛型的操作类
// 定义一个方法,实现任意类型数组中两个位置值得调换 public static <T> T[] function(T[] array, int i, int j) { T temp = array[i]; array[i] = array[j]; array[j] = temp; return array; }
-
-
泛型的嵌套使用
-
在使用集合时,我们可以使用泛型嵌套:
Set<Entry<Integer, String>> entrys = map.entrySet();
-
-
示例:
package day12_泛型; import org.junit.Test; import java.util.*; /** * @author xiao儿 * @date 2019/9/3 19:16 * @Description GenericDemo */ public class GenericDemo { @Test public void test1() { List<String> list = new ArrayList<>(); list.add("Tom"); // list.add(10); // list.add(new Object()); for (int i = 0; i <list.size(); i++) { // 如果我们不确定集合中的元素类型,那么我们需要在处理元素时进行判断元素的类型,才可以执行不同的操作 } } @Test public void test2() { Node<Number> numberNode = new Node<>(); Node<Integer> integerNode = new Node<>(); } @Test public void test3() { Node<Number> numberNode = new Node<>(10); Node<Integer> integerNode = new Node<>(20); getData(numberNode); // 不支持赋值 // getData(integerNode); // numberNode = integerNode; getDate2(integerNode); getUpperNumberData(numberNode); getUpperNumberData(integerNode); } public static void getData(Node<Number> node) { System.out.println(node.getData()); } /** * 使用通配符定义泛型类型,此时只能输出,不能修改 * @param node */ public static void getDate2(Node<?> node) { // node.setData(20); System.out.println(node.getData()); } public static void getUpperNumberData(Node<? extends Number> data) { // 只能是 Number 类或其子类 System.out.println("data=" + data.getData()); // data.setData(10); } /** * 泛型方法 * @param array * @param i * @param j * @param <T> * @return */ public static <T> T[] function(T[] array, int i, int j) { T temp = array[i]; array[i] = array[j]; array[j] = temp; return array; } @Test public void test4() { String[] arrays = {"Tom", "Lily", "Bin", "Jack"}; String[] strs = function(arrays, 0, 2); System.out.println(Arrays.toString(strs)); } @Test public void test5() { Map<Integer, String> map = new HashMap<>(); map.put(1, "Tom"); map.put(2, "Lily"); Set<Map.Entry<Integer, String>> entrySet = map.entrySet(); for (Map.Entry entry : entrySet) { System.out.println(entry.getKey() + "-" + entry.getValue()); } } }
(十三)泛型
最新推荐文章于 2021-02-19 14:26:13 发布