• JavaSE泛型讲解


    1. 泛型概述

    什么是泛型,为什么要用泛型?

    泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

    泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

    2. 泛型举例

    List arrayList = new ArrayList();
    arrayList.add("aaaa");
    arrayList.add(100);
    
    for(int i = 0; i< arrayList.size();i++){
        String item = (String)arrayList.get(i);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这段代码是不能执行的,原因也很简单,100并不是字符串,无法强转输出,那如何避免这中问题呢?答案很简单,采用泛型

    List arrayList = new ArrayList<String>();
    
    • 1

    这样的话,我们的arrayList中就只能存储String类型的数据。

    3. 泛型的优点

    1. 编译时,检查添加元素的类型,提高了安全性。
    2. 减少了类型转换的次数,提高效率。
    3. 不再提示编译警告

    4. 泛型介绍

    1. 泛型又称参数化类型,是jdk5.0出现的新特性,解决数据类型的安全性问题。
    2. 在类声明或实例化时只要指定好需要的具体的类型即可。
    3. Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生ClassCastException 异常,同时代码更加简洁,健壮。
    4. 泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型,或者是参数类型。

    5. 泛型的语法

    interface 接口<T>{}class<k,v>{}
    
    • 1

    说明

    1. 其中,T,K,V不代表值,而是表示类型。
    2. 任意字母都可以。常用T表示,是Type的缩写。

    6. 泛型使用

    6.1 简单了解
    class Person<E> {
        	E s ;//E 表示 s 的数据类型, 该数据类型在定义 Person 对象的时候指定,即在编译期间,就确定 E 是什么类型
        	public Person(E s) {//E 也可以是参数类型
        	this.s = s;
        }
        	public E f() {//返回类型使用 E
        	return s;
        }
       	 	public void show() {
        	System.out.println(s.getClass());//显示 s 的运行类型
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    我们实例化一个Person对象

    Person person = new Person(“要开学了”);

    对比下面理解

    class Person {
    		String s ;//E 表示 s 的数据类型, 该数据类型在定义 Person 对象的时候指定,即在编译期间,就确定 E是什么类型
    		public Person(String s) {//E 也可以是参数类型
    		this.s = s;
    	}
    		public String f() {//返回类型使用 E
    		return s;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    6.2 进一步了解

    泛型的实例化

    要在类名后面指定类型参数的值(类型)例如:

    List<String> list = new ArrayList<String>();
    Iterator<Customer> iterator = customer.iterator();
    
    • 1
    • 2

    实例化举例

    使用泛型方式给 HashSet 放入 3 个学生对象

    HashSet<Student> students = new HashSet<Student>();
    students.add(new Student("jack", 18));
    students.add(new Student("tom", 28));
    students.add(new Student("mary", 19));
    //遍历
    for (Student student : students) {
    System.out.println(student);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用泛型方式给 HashMap 放入 3 个学生对象

    //使用泛型方式给 HashMap 放入 3 个学生对象
    //K -> String V->Student
    HashMap<String, Student> hm = new HashMap<String, Student>();
    /*
    public class HashMap {}
    */
    hm.put("lucy", new Student("lucy", 38));
    hm.put("smith", new Student("smith", 48));
    hm.put("jack", new Student("jack", 28));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    6.3 泛型接口

    泛型接口的使用与泛型的定义及使用基本相同

    //定义一个泛型接口
    public interface Generator<T> {
        public T next();
    }
    
    • 1
    • 2
    • 3
    • 4

    未传参时

    /**
     * 未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
     * 即:class FruitGenerator implements Generator{
     * 如果不声明泛型,如:class FruitGenerator implements Generator,编译器会报错:"Unknown class"
     */
    class FruitGenerator<T> implements Generator<T>{
        @Override
        public T next() {
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    传参后

    /**
     * 传入泛型实参时:
     * 定义一个生产器实现这个接口,虽然我们只创建了一个泛型接口Generator
     * 但是我们可以为T传入无数个实参,形成无数种类型的Generator接口。
     * 在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型
     * 即:Generator,public T next();中的的T都要替换成传入的String类型。
     */
    public class FruitGenerator implements Generator<String> {
    
        private String[] fruits = new String[]{"Apple", "Banana", "Pear"};
    
        @Override
        public String next() {
    
            return fruits[1];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    7. 泛型使用的注意事项

    1. interface List{},public class HashSet{} 等等

      其中T,E只能是引用类型,主要就是int等类型要使用其包装类例如:

      List list = new ArrayList() //正确

      List list = new ArrayList() //错误,int不是引用类型。

    2. 在给泛型指定具体类型后,可以传入该类型或者其子类型。

    3. 泛型使用形式

      List list1 = new ArrayList();

      List list2 = new ArrayList<>();注意,后面的泛型可以省略

    4. List list3 = new ArrayList();

      如果我们这么写,默认给他的泛型是Object类型

    8. 结语

    泛型在Java开发中非常常用,就如集合般,他俩常常是一起使用的,注意语法即可,后面写小项目时自己就会用了,不需要直接就理解,后面的学习中会经常看见,再回过头看你会发现,泛型也就这么回事。

  • 相关阅读:
    grafana将label值转化为metrics
    Gazebo、Rviz 结合 ORB-SLAM3 实现运动规划及定位
    GRACE-FO L2产品的发布说明 - 版本UTCSR RL-06.1产品
    HTML网页规划与设计【冬季奥林匹克运动会——带报告5200字】HTML+CSS+JavaScript
    卷积神经网络 - 汇聚层
    uniapp 中添加 vconsole
    博客园众包平台:50w+驱动开发大单,全园找人接单
    JMeter参数化4种实现方式
    学习代码20231106
    Electron常见问题 62 - Electron配置私有化sentry的方法
  • 原文地址:https://blog.csdn.net/m0_64102491/article/details/126822260