Java—— 泛型详解

[复制链接]
发表于 2025-9-12 18:05:51 | 显示全部楼层 |阅读模式
泛型概述

泛型是JDK5中引入的特性,可以在编译阶段束缚操纵的数据范例,并举行检查。
泛型的格式:<数据范例>
注意:泛型只能支持引用数据范例。
泛型的利益

没有泛型的时间,可以往聚集中添加恣意范例的数据,默认将聚集中全部元素的数据范例都提升为Object范例,但是在获取数据的时间,数据都是Object范例,以是无法直接利用原来范例的特有方法,必要举行强转,如果不知道该强转成什么数据范例就没办法了。
此时推出了泛型,可以在添加数据的时间就把范例举行同一。
而且我们在获取数据的时间,也省的强转了,非常的方便。 
泛型的细节

1.泛型中不能写根本数据范例
2.指定泛型的详细范例的聚集,添加数据时,可以添加该类范例或者其子类范例的数据
3.如果不写泛型,范例默认是Object 
泛型的分类

在类背面界说泛型为泛型类
在方法上面界说泛型为泛型方法
在接口背面界说泛型为泛型接口 
泛型类

利用场景

当一个类中,某个变量的数据范例不确定时,就可以界说带有泛型的类
格式

修饰符 class 类名 <范例> {
        ...
}
举例

public class MyArrayList <E> {
        ...
}
此处E可以明白为变量,但是不是用来记载数据的,而是记载数据的范例,常用T、E、K、V字母表示,创建该类对象时,E就确定范例
如果该类要利用多种范例的数据,可在<>中写多种变量通过逗号分隔,比方<E,T,K>
代码演示 

要求:界说一个类实现ArrayList中的部分方法 
  1. import java.util.Arrays;
  2. //定义一个类实现ArrayList中的部分方法
  3. public class MyArrayList<E>{
  4.     //成员变量
  5.     private Object[] obj = new Object[10];
  6.     private int size;
  7.     public MyArrayList() {
  8.     }
  9.     //添加元素方法
  10.     public boolean add(E e){
  11.         obj[size] = e;
  12.         size++;
  13.         return true;
  14.     }
  15.     //get方法
  16.     public E get(int i){
  17.         return (E)obj[i];
  18.     }
  19.     @Override
  20.     public String toString() {
  21.         return obj.toString();
  22.     }
  23. }
复制代码
测试类
  1. public class Test {
  2.     public static void main(String[] args) {
  3.         MyArrayList<String> mal1 = new MyArrayList<>();
  4.         mal1.add("aaa");
  5.         mal1.add("bbb");
  6.         System.out.println(mal1.get(1));//bbb
  7.         MyArrayList<Integer> mal2 = new MyArrayList<>();
  8.         mal2.add(1);
  9.         mal2.add(2);
  10.         System.out.println(mal2.get(1));//2
  11.     }
  12. }
复制代码
 
泛型方法

利用场景

当一个方法,某个变量的数据范例不确定时,就可以界说带有泛型的方法
格式

修饰符 <范例> 返回值范例 方法名(范例 变量名){
        ...
}
举例

public <E> void show(E e){
        ...
}
调用该方法时E就确定范例
代码演示

界说一个工具类istUtil,类中界说一个静态方法addAll,用来添加多个聚集的元素。
  1. import java.util.ArrayList;
  2. //定义一个工具类:ListUtil
  3. //类中定义一个静态方法addAll,用来添加多个集合的元素。
  4. public class ListUtil {
  5.     private ListUtil() {
  6.     }
  7.     public static <E> void addAll1(ArrayList<E> list, E e1, E e2) {
  8.         list.add(e1);
  9.         list.add(e2);
  10.     }
  11.     //参数个数不确定时使用E...e
  12.     public static <E> void addAll2(ArrayList<E> list, E... e) {
  13.         for (E element : e) {
  14.             list.add(element);
  15.         }
  16.     }
  17. }
复制代码
 测试类
  1. import java.util.ArrayList;
  2. public class Test {
  3.     public static void main(String[] args) {
  4.         ArrayList<String> list1 = new ArrayList<>();
  5.         ListUtil.addAll1(list1, "aaa", "bbb");
  6.         System.out.println(list1);//[aaa, bbb]
  7.         ArrayList<Integer> list2 = new ArrayList<>();
  8.         ListUtil.addAll2(list2, 1, 2, 3, 4);
  9.         System.out.println(list2);//[1, 2, 3, 4]
  10.     }
  11. }
复制代码

细节

泛型类和泛型方法泛型方法都能办理方法中形参范例不确定的题目
区别:
利用类名背面界说的泛型:全部方法都能用
在方法说明上界说本身的泛型:只有本方法能用
泛型接口

利用场景

界说在接口名背面,表示接口实现类的范例
如何利用一个带泛型的接口

方式1:

实现类给出详细范例

方式2:

实现类连续泛型,创建对象时再确定
 
泛型的通配符

泛型不具备继承性,但是数据具备继承性。
指定泛型的详细范例的聚集,添加数据时,可以添加该类范例或者其子类范例的数据
但是调用方法时,形参的泛型内里写的是什么范例,那么只能通报什么范例的数据
此时我们就可以利用泛型的通配符:
?也表示不确定的范例
? extends E:表示可以通报E或者E全部的子类范例
? super E:表示可以通报E或者E全部的父类范例 
练习

 

测试类中界说一个方法用于豢养动物
public static void keepPet(ArrayList<???> list){
        //遍历聚集,调用动物的eat方法
}
要求1:该方法能养全部品种的猫,但是不能养狗
要求2:该方法能养全部品种的狗,但是不能养猫
要求3:该方法能养全部的动物,但是不能通报其他范例
  1. import java.util.ArrayList;
  2. public class Test {
  3.     public static void main(String[] args) {
  4.         ArrayList<PersianCat> list1 = new ArrayList<>();
  5.         ArrayList<LiHuaCat> list2 = new ArrayList<>();
  6.         ArrayList<TeddyDog> list3 = new ArrayList<>();
  7.         ArrayList<HuskyDog> list4 = new ArrayList<>();
  8.         keepPet(list1);
  9.         keepPet(list2);
  10.         keepPet(list3);
  11.         keepPet(list4);
  12.     }
  13.     //测试类中定义一个方法用于饲养动物
  14.     //要求1:该方法能养所有品种的猫,但是不能养狗
  15.     //public static void keepPet(ArrayList<? extends Cat> list) {}
  16.     //要求2:该方法能养所有品种的狗,但是不能养猫
  17.     //public static void keepPet(ArrayList<? extends Dog> list) {}
  18.     //要求3:该方法能养所有的动物,但是不能传递其他类型
  19.     public static void keepPet(ArrayList<? extends Animal> list) {}
  20. }   
  21.     abstract class Animal {
  22.         public abstract void eat();
  23.     }
  24.     abstract class Cat extends Animal {
  25.     }
  26.     abstract class Dog extends Animal {
  27.     }
  28.     class PersianCat extends Cat {
  29.         @Override
  30.         public void eat() {
  31.             System.out.println("波斯猫吃东西");
  32.         }
  33.     }
  34.     class LiHuaCat extends Cat {
  35.         @Override
  36.         public void eat() {
  37.             System.out.println("狸花猫吃东西");
  38.         }
  39.     }
  40.     class TeddyDog extends Dog {
  41.         @Override
  42.         public void eat() {
  43.             System.out.println("泰迪狗吃东西");
  44.         }
  45.     }
  46.     class HuskyDog extends Dog {
  47.         @Override
  48.         public void eat() {
  49.             System.out.println("哈士奇吃东西");
  50.         }
  51.     }
复制代码
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表