• java之泛型


    目录

    泛型

    泛型的优缺点

    集合中使用泛型案例

    泛型总结

    自定义泛型结构

    泛型类

    泛型类案例 

    普通情况

    继承情况

    泛型类可以定义多个参数类型

    泛型类总结

    泛型方法

    泛型方法案例

    泛型方法总结

    通配符

    经典案例

    通配符类型变量操作

    通配符总结

    泛型受限

    泛型

    含义:集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存的是什么类型的对象。所以在jdk1.5之后使用泛型来解决。因为这个时候除了元素的类型不确定,其他部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此,此时把元素类型设计成一个参数,这个类型参数叫做泛型。

    泛型形式:<类型>

    泛型的优缺点

    • 不使用泛型的缺点:一般我们在使用的时候,基本往集合中存入的都是相同类型的数据,便于管理,所以,如果什么引用数据类型都可以存入集合就不方便
    • 加入泛型的优点:编译时期就可以对类型进行检查,不是泛型那么对应的类型就不可以加入该集合

    集合中使用泛型案例

    1. public class Tset6 {
    2. public static void main(String[] args) {
    3. Object o = new Object();
    4. String s = new String();
    5. o=s;//多态的一种形式
    6. Object[] objects = new Object[10];
    7. String[] strings = new String[10];
    8. objects=strings;//多态的一种形式
    9. ArrayList<Object> l1 = new ArrayList<>();
    10. ArrayList<String> l2 = new ArrayList<>();
    11. //l1=l2;报错
    12. //因为l1,l2底层都是Object类型的数组,而这个泛型仅仅是对我们写代码时进行限制,所以l1和l2本质上完全没继承关系,全是Object类型
    13. }
    14. }

    泛型总结

    • 泛型就相当于一个标签,其是jdk1.5以后推出的
    • 泛型实际上就是一个<>引起来的参数类型,这个参数类型只有在确定的时候才会确定具体类型
    • 使用泛型以后可以确定集合中存放的数据类型,并且数据类型是否一致在编译期就会检查出来
    • 泛型的类型都是引用数据类型,不能是基本数据类型
    • 使用泛型之后,后续的遍历等操作简单
    • 在jdk1.7以后ArrayList integers = new ArrayList<>()(new ArrayList<>())里面的<>(钻石运算符)可以不用写类型了,因为后面的<>会根据前面的泛型进行类型推断
    • A和B是子类父类关系,但G和G不存在继承关系,其是并列关系,因为泛型的本质就是限定,G和G底层都是Object数组

    自定义泛型结构

    • 泛型类
    • 泛型接口
    • 泛型方法

    泛型类

    1. //普通类
    2. public class GenericTest {}
    3. //泛型类
    4. public class GenericTest<A> {}

    泛型类案例 

    普通情况

    1. //泛型类
    2. public class GenericTest {
    3. int age;
    4. String name;
    5. E sex;
    6. public void method1(E n){
    7. System.out.println(n);
    8. }
    9. public void method2(E[] m){
    10. System.out.println(Arrays.toString(m));
    11. }
    12. }
    13. class Test{
    14. public static void main(String[] args) {
    15. //实例化时不指定泛型默认为Object
    16. GenericTest gt1 = new GenericTest();
    17. gt1.method1("hello");
    18. gt1.method1(17);
    19. gt1.method2(new String[]{"a","b","c"});
    20. gt1.method2(new Integer[]{1,2,3});
    21. //实例化的时候指定泛型
    22. GenericTest<String> gt2 = new GenericTest<>();
    23. gt2.method1("必须是string了,我失去了自由");
    24. gt2.sex="男";//因为上面已经指定了泛型为string,因此sex为string类型
    25. }
    26. }

    继承情况

    父类指定泛型,子类可以直接使用父类方法属性等

    1. //泛型类
    2. public class GenericTest<E> {
    3. int age;
    4. String name;
    5. E sex;
    6. public void method1(E n){
    7. System.out.println(n);
    8. }
    9. public void method2(E[] m){
    10. System.out.println(Arrays.toString(m));
    11. }
    12. }
    13. class SubGenericTest extends GenericTest<Integer>{}
    14. class Test{
    15. public static void main(String[] args) {
    16. //父类指定泛型,子类可以直接使用
    17. SubGenericTest sgt1 = new SubGenericTest();
    18. sgt1.method1(12);//这里父类指定泛型了,因此必须传Integer类型
    19. }
    20. }

    父类不指定泛型,那么子类直接变成一个泛型类,这个泛型类型可以在子类创建对象时确定

    1. public class GenericTest {
    2. int age;
    3. String name;
    4. E sex;
    5. public void method1(E n){
    6. System.out.println(n);
    7. }
    8. public void method2(E[] m){
    9. System.out.println(Arrays.toString(m));
    10. }
    11. }
    12. class SubGenericTest extends GenericTest{}
    13. class Test{
    14. public static void main(String[] args) {
    15. SubGenericTest<String> sgt1 = new SubGenericTest();
    16. sgt1.method1("hello");
    17. }
    18. }

    泛型类可以定义多个参数类型

    1. public class GenericTest1<A,B,C> {
    2. A age;
    3. B name;
    4. C sex;
    5. public void method(A m,B n,C x){
    6. System.out.println(m);
    7. System.out.println(n);
    8. System.out.println(x);
    9. }
    10. //泛型类的构造器不写泛型类型
    11. public GenericTest1(){}
    12. }

    泛型类总结

    • <>里面就是一个参数类型,这个类型现在是不确定的,相当于一个占位符,但是现在确定它是一个引用数据类型
    • 实例化的时候才会确定泛型类型
    • 遇到继承情况,父类为泛型类,若父类指定了泛型,那么子类可以直接使用
    • 父类不指定泛型,那么子类直接变成一个泛型类,这个泛型类型可以在子类创建对象时确定
    • 若在实例化的时候,不明确指定泛型,那么默认此泛型为Object类型
    • 泛型类可以定义多个参数类型
    • 泛型类型的构造器不加<>,就按常规写法即可
    • 不同泛型的引用类型不可以相互赋值
    • 泛型如果不指定,那么就会被擦除,对应类型为Object类型
    • 泛型类里的静态方法不能使用类的泛型(因为static方法优先于对象存在,而泛型是创建对象时指定的,怎么用)
    • 创建泛型数组:A[] i=(A[])new Object[10]

    泛型方法

    1. public class GenericTest2 {
    2. //不是泛型方法
    3. public void method1(E e){}
    4. //是泛型方法
    5. public void method2(T t){}
    6. public void method3(T t,U u){}
    7. }

    泛型方法的要求:这个方法的泛型的参数类型要和当前类的泛型无关。

    注意:泛型方法定义的时候需要在返回值类型前面加上,若不加的话会把T当作一种数据类型,然而代码中并没有T类型,便会报错。

    泛型方法案例

    1. public class GenericTest2 {
    2. //不是泛型方法
    3. public void method1(E e){}
    4. //是泛型方法
    5. public void method2(T t){}
    6. public static void method3(T t,U u){}
    7. }
    8. class Test5{
    9. public static void main(String[] args) {
    10. GenericTest2<Object> gt2 = new GenericTest2<>();
    11. gt2.method2("hello");//调用方法时确定泛型方法为字符串类型
    12. gt2.method2(12);//调用方法时确定泛型方法为Integer类型
    13. gt2.method3("hello", true);//调用方法时分别确定了2个泛型
    14. }
    15. }

    泛型方法总结

    • 不是带有泛型的方法就是泛型方法
    • 泛型方法的泛型类型是在方法调用时确定的
    • 泛型方法的泛型类型可以是多个
    • 泛型方法可以是静态方法

    通配符

    泛型通配符写法:

    经典案例

    1. public class Test7 {
    2. public static void main(String[] args) {
    3. ArrayList<Object> objects = new ArrayList<>();
    4. ArrayList<String> strings = new ArrayList<>();
    5. ArrayList<Integer> integers = new ArrayList<>();
    6. List> list=null;
    7. list=objects;
    8. list=strings;
    9. list=integers;
    10. }
    11. }

    通配符类型变量操作

    1. public void method3(List list){
    2. //遍历
    3. for (Object a:list){
    4. System.out.println(a);
    5. }
    6. //数据的写入操作
    7. //list.add("abc");报错,因为什么类型都可能接收到,接收到的类型若不是String类型的泛型就没意义了
    8. list.add(null);//可行,但没意义
    9. //数据的读取操作
    10. Object o = list.get(0);
    11. System.out.println(o);
    12. }

    通配符总结

    泛型受限

    1. public class Person extends Object{}
    2. class Student extends Person{}
    3. class Test8{
    4. public static void main(String[] args) {
    5. //下面3个集合不具备子类父类的关系
    6. ArrayList<Object> objects = new ArrayList<>();
    7. ArrayList<Person> persons = new ArrayList<>();
    8. ArrayList<Student> students = new ArrayList<>();
    9. //泛型的上限
    10. //List是List的父类,也是List的父类
    11. Listextends Person> list1=null;
    12. //list1=objects;报错
    13. list1=persons;
    14. list1=students;
    15. //泛型的下限
    16. //List是List的父类,也是List的父类
    17. Listsuper Person> list2=null;
    18. list2=objects;
    19. list2=persons;
    20. //list2=students;报错
    21. }
    22. }

  • 相关阅读:
    基础IO —— Linux
    Latex在图片中添加文字
    WWW‘22 推荐系统论文之多任务与对比学习篇
    Linux - 使用objcopy命令修改符号的作用域避免同名符号冲突
    网络安全(黑客)自学
    [附源码]计算机毕业设计JAVAjsp-在线排课系统
    负载均衡四层和七层的区别
    树的基本概念介绍
    Nacos的动态配置源码解析
    Android学习笔记 9. PopupWindow
  • 原文地址:https://blog.csdn.net/m0_60027772/article/details/126144739