码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 第十二章:泛型(Generic)


    目录

    12.1:为什么要有泛型?

    12.2:在集合中使用泛型

    12.3:自定义泛型结构

    12.4:泛型在继承上的体现

    12.5:通配符的使用


    12.1:为什么要有泛型?

            泛型:(标签)允许在定义类、接口时候通过一个标识来表示类中某个属性的类型或者是某个方法的返回值及参数类型。这个类型、参数将在使用时(例如:继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实际的类型参数,也称为类型实参)

            JDK 1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持,从而可以在声明集合变量、创建集合对象时传入类型实参

    12.2:在集合中使用泛型

    1. package com.jiayifeng.java;
    2. import org.junit.Test;
    3. import java.util.*;
    4. /**
    5. * author 爱编程的小贾
    6. * create 2023-10-08 19:45
    7. *
    8. * 一:泛型的使用
    9. * 1.jdk 1.5新增的特性
    10. * 2.在集合中使用泛型:
    11. * 总结:
    12. * ①集合接口或集合类在jdk 5.0时都修改为带泛型的结构
    13. * ②在实例化集合类时,可以指明具体的泛型类型
    14. * ③指明完以后,在集合类或接口中凡是定义类或接口时,内部结构使用到类的泛型的位置,都
    15. * 指定为实例化的泛型类型
    16. * 比如:add(E e) ---> 实例化以后:add(Integer e)
    17. * ④注意点:泛型的类型必须是类,不能是基本数据类型。需要用到基本数据类型的位置,拿包装类替换
    18. * ⑤如果实例化时,没有指明泛型的类型。默认类型为java.lang.Object类型
    19. */
    20. public class GenericTest {
    21. @Test
    22. public void test1(){
    23. // 在集合中使用泛型之前的情况:
    24. ArrayList list = new ArrayList();
    25. // 需求:存放学生的成绩
    26. list.add(78);
    27. list.add(43);
    28. list.add(99);
    29. list.add(67);
    30. // 问题一:类型不安全
    31. // list.add("Tom");
    32. for(Object score : list){
    33. // 问题二:强转时,可能出现ClassCastException
    34. int stuScore = (Integer) score;
    35. System.out.println(stuScore);
    36. }
    37. }
    38. @Test
    39. public void test2(){
    40. // 在集合中使用泛型的情况:以ArrayList为例
    41. ArrayList list = new ArrayList();
    42. list.add(78);
    43. list.add(67);
    44. list.add(100);
    45. // 编译时,就会进行类型检查,保证数据的安全
    46. // list.add("Tom");
    47. 方式一:
    48. // for(Integer score : list){
    49. 避免了强转操作
    50. // System.out.println(score);
    51. // }
    52. // 方式二:
    53. Iterator iterator = list.iterator();
    54. while(iterator.hasNext()){
    55. int stuScore = iterator.next();
    56. System.out.println(stuScore);
    57. }
    58. }
    59. @Test
    60. public void test3(){
    61. // 在集合中使用泛型的情况:以HashMap为例
    62. // HashMap map = new HashMap();
    63. // jdk 7新特性:类型推断
    64. HashMap map = new HashMap();
    65. map.put("Tom",23);
    66. map.put("Jerry",42);
    67. map.put("Jack",17);
    68. map.put("Marry",24);
    69. // 泛型的嵌套
    70. Set> entry = map.entrySet();
    71. Iterator> iterator = entry.iterator();
    72. while (iterator.hasNext()) {
    73. Map.Entry e = iterator.next();
    74. String key = e.getKey();
    75. Integer value = e.getValue();
    76. System.out.println(key + "---" + value);
    77. }
    78. }
    79. }

    12.3:自定义泛型结构

            ①泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:

            ②实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致

            ③泛型不同的引用不可以相互赋值

            ④如果泛型结构是一个接口或抽象类,则不可以创建泛型类的对象

            ⑤jdk 1.7,泛型的简化操作:ArrayList flist = new ArrayList<>();

            ⑥泛型的指定中不能使用基本数据类型,可以使用包装类替换

            ⑦在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态属性的类型、非静态方法的参数类型、非静态方法的返回值类型。但在静态方法中不能使用类的泛型

            ⑧异常类不能是泛型的

            ⑨父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型:

                    子类不保留父类的泛型:按需实现

                            没有类型 擦除

                            具体类型

                    子类保留父类的泛型:泛型子类

                            全部保留

                            部分保留

            结论:子类必须是“富二代”,子类除了指定或保留父类的泛型,还可以增加自己的泛型

    1. package com.jiayifeng.java;
    2. import org.junit.Test;
    3. import java.util.ArrayList;
    4. import java.util.List;
    5. /**
    6. * author 爱编程的小贾
    7. * create 2023-10-09 15:11
    8. *
    9. * 一:如何自定义泛型结构:泛型类、泛型接口;泛型方法
    10. * 1.如何定义泛型类 、泛型接口
    11. */
    12. public class GenericTest1 {
    13. @Test
    14. public void test(){
    15. // 如果定义了泛型类,实例化没有指明类的泛型,则认为此泛型类型为Object类型
    16. // 要求:如果定义的类是带泛型的,建议在实例化时要指明类的泛型
    17. Order order = new Order();
    18. order.setOrderT(123);
    19. order.setOrderT("ABC");
    20. // 建议:实例化时指明类的泛型
    21. Order order1 = new Order("orderAA",1001,"orderAA");
    22. order1.setOrderT("AA:hello");
    23. }
    24. @Test
    25. public void test1(){
    26. SubOrder subOrder = new SubOrder();
    27. // 由于子类在继承带泛型的父类时指明了泛型类型。则实例化子类对象时,不需要再指明泛型
    28. subOrder.setOrderT(1122);
    29. SubOrder1 subOrder1 = new SubOrder1();
    30. subOrder1.setOrderT("Order1...");
    31. }
    32. @Test
    33. public void test2(){
    34. // 泛型不同的引用不能相互赋值
    35. ArrayList list1 = null;
    36. ArrayList list2 = null;
    37. // error
    38. // list1 = list2;
    39. }
    40. // 测试泛型方法
    41. @Test
    42. public void test3(){
    43. Order order = new Order<>();
    44. Integer[] arr = new Integer[]{1,2,3,4};
    45. // 泛型方法在调用时,指明泛型参数的类型
    46. List list = order.copyFromArrayToList(arr);
    47. System.out.println(list);
    48. }
    49. }
    1. package com.jiayifeng.java;
    2. import java.util.ArrayList;
    3. import java.util.Arrays;
    4. import java.util.List;
    5. /**
    6. * author 爱编程的小贾
    7. * create 2023-10-09 15:04
    8. *
    9. * 一:自定义泛型类
    10. */
    11. public class Order {
    12. String orderName;
    13. int orderId;
    14. // 类的内部结构就可以使用类的泛型
    15. T orderT;
    16. public Order(){
    17. // 编译不通过
    18. // T[] arr = new T[10];
    19. // 编译通过
    20. T[] arr = (T[])new Object[10];
    21. }
    22. public Order(String orderName,int orderId,T orderT){
    23. this.orderName = orderName;
    24. this.orderId = orderId;
    25. this.orderT = orderT;
    26. }
    27. // 如下的三个方法都不是泛型方法
    28. public T getOrderT() {
    29. return orderT;
    30. }
    31. public void setOrderT(T orderT) {
    32. this.orderT = orderT;
    33. }
    34. @Override
    35. public String toString() {
    36. return "Order{" +
    37. "orderName='" + orderName + '\'' +
    38. ", orderId=" + orderId +
    39. ", orderT=" + orderT +
    40. '}';
    41. }
    42. // 静态方法中不可以使用类的泛型
    43. // 静态方法早于类的创建
    44. // public static void show(T orderT){
    45. // System.out.println(orderT);
    46. // }
    47. // 泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系
    48. // 换句话说,泛型方法所属的类是不是泛型类都没有关系
    49. // 泛型方法,可以声明为静态的。原因:泛型参数是在调用方法时确定的。并非在实例化类时确定
    50. public static List copyFromArrayToList(E[] arr){
    51. ArrayList list = new ArrayList<>();
    52. for(E e : arr){
    53. list.add(e);
    54. }
    55. return list;
    56. }
    57. }
    1. package com.jiayifeng.java;
    2. /**
    3. * author 爱编程的小贾
    4. * create 2023-10-09 15:21
    5. */
    6. public class SubOrder extends Order{//SubOrder:不是泛型类
    7. }
    1. package com.jiayifeng.java;
    2. /**
    3. * author 爱编程的小贾
    4. * create 2023-10-09 15:24
    5. */
    6. public class SubOrder1 extends Order{//SubOrder1:仍然是泛型类
    7. }

    12.4:泛型在继承上的体现

    12.5:通配符的使用

    1. package com.jiayifeng.java2;
    2. import org.junit.Test;
    3. import java.util.AbstractList;
    4. import java.util.ArrayList;
    5. import java.util.Iterator;
    6. import java.util.List;
    7. /**
    8. * author 爱编程的小贾
    9. * create 2023-10-09 16:32
    10. *
    11. * 一:泛型在继承方面的使用
    12. *
    13. * 二:通配符的使用
    14. */
    15. public class GenericTest {
    16. /*
    17. 1.泛型在继承方面的使用
    18. 虽然类A是类B的父类,但是G和G二者不具备子父类关系,二者是并列关系
    19. 补充:类A是类B的父类,A是B的父类
    20. */
    21. @Test
    22. public void test(){
    23. Object obj = null;
    24. String str = null;
    25. obj = str;
    26. Object[] arr1 = null;
    27. String[] arr2 = null;
    28. arr1 = arr2;
    29. List list1 = null;
    30. List list2 = new ArrayList();
    31. // 此时的list1和list2的类型不具有子父类关系
    32. // list1 = list2;
    33. /*
    34. 反证法:
    35. 假设list1 = list2;
    36. list1.add(123);导致混入非String的数据。出错
    37. */
    38. }
    39. @Test
    40. public void test2(){
    41. AbstractList list1 = null;
    42. List list2 = null;
    43. ArrayList list3 = null;
    44. list1 = list3;
    45. list2 = list3;
    46. }
    47. /*
    48. 2.通配符的使用
    49. 通配符:?
    50. 类A是类B的父类,G和G是没有关系的,二者共同的父类是:G
    51. */
    52. @Test
    53. public void test3(){
    54. List list1 = null;
    55. List list2 = null;
    56. List list = null;
    57. list = list1;
    58. list = list2;
    59. print(list1);
    60. print(list2);
    61. //
    62. List list3 = new ArrayList<>();
    63. list3.add("AA");
    64. list3.add("BB");
    65. list3.add("CC");
    66. list = list3;
    67. // 添加(写入):对于List而言,不可以向其内部添加数据
    68. // 除了添加null之外
    69. // list.add("DD");
    70. list.add(null);
    71. // 获取(读取):允许读取数据,读取的数据类型为Object
    72. Object o = list.get(0);
    73. System.out.println(o);
    74. }
    75. public void print(List list){
    76. Iterator iterator = list.iterator();
    77. while (iterator.hasNext()) {
    78. Object obj = iterator.next();
    79. System.out.println(obj);
    80. }
    81. }
    82. /*
    83. 3.有限制条件的通配符的使用
    84. ? extends A:
    85. G 可以作为G和G的父类,其中B是A的子类
    86. ? super A
    87. G 可以作为G和G的父类,其中B是A的父类
    88. */
    89. @Test
    90. public void test4(){
    91. Listextends Person> list1 = null;
    92. Listsuper Person> list2 = null;
    93. List list3 = new ArrayList();
    94. List list4 = new ArrayList();
    95. List list5 = new ArrayList();
    96. list1 = list3;
    97. list1 = list4;
    98. // list1 = list5;
    99. // list2 = list3;
    100. list2 = list4;
    101. list2 = list5;
    102. // 读取数据
    103. list1 = list4;
    104. Person p = list1.get(0);
    105. list2 = list4;
    106. Object object = list2.get(0);
    107. // 写入数据
    108. list2.add(new Person());
    109. list2.add(new Student());
    110. }
    111. }
      1. package com.jiayifeng.java2;
      2. /**
      3. * author 爱编程的小贾
      4. * create 2023-10-09 17:17
      5. */
      6. public class Person {
      7. }
      1. package com.jiayifeng.java2;
      2. /**
      3. * author 爱编程的小贾
      4. * create 2023-10-09 17:17
      5. */
      6. public class Student extends Person{
      7. }
    112. 相关阅读:
      【C++】二叉搜索树
      Linux 内核参数:oom_kill_allocating_task
      二手车价格预测 | 构建AI模型并部署Web应用 ⛵
      梦想CAD控件,CAD插件,网页CAD 2022.06.22更新
      【腾讯云 Cloud Studio 实战训练营】使用Cloud Studio快速构建React完成点餐H5页面还原
      观察者模式(大话设计模式)C/C++版本
      支持 equals 相等的对象(可重复对象)作为 WeakHashMap 的 Key
      【操作系统笔记十四】科普:POSIX 是什么
      被Chatgpt碾压的打工人与大学生,准备反击!
      python requests请求一个api接口报错
    113. 原文地址:https://blog.csdn.net/weixin_63925896/article/details/133688572
      • 最新文章
      • 攻防演习之三天拿下官网站群
        数据安全治理学习——前期安全规划和安全管理体系建设
        企业安全 | 企业内一次钓鱼演练准备过程
        内网渗透测试 | Kerberos协议及其部分攻击手法
        0day的产生 | 不懂代码的"代码审计"
        安装scrcpy-client模块av模块异常,环境问题解决方案
        leetcode hot100【LeetCode 279. 完全平方数】java实现
        OpenWrt下安装Mosquitto
        AnatoMask论文汇总
        【AI日记】24.11.01 LangChain、openai api和github copilot
      • 热门文章
      • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
        奉劝各位学弟学妹们,该打造你的技术影响力了!
        五年了,我在 CSDN 的两个一百万。
        Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
        面试官都震惊,你这网络基础可以啊!
        你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
        心情不好的时候,用 Python 画棵樱花树送给自己吧
        通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
        13 万字 C 语言从入门到精通保姆级教程2021 年版
        10行代码集2000张美女图,Python爬虫120例,再上征途
      Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
      正则表达式工具 cron表达式工具 密码生成工具

      京公网安备 11010502049817号