JavaSe—泛型

目录

1、认识泛型

2、泛型类

[2.1 自定义泛型类](#2.1 自定义泛型类)

3、泛型接口

[3.1 自定义泛型接口](#3.1 自定义泛型接口)

4、泛型方法

5、通配符、上下限

6、泛型支持的类型

[6.1 包装类](#6.1 包装类)

[6.2 包装类具体的其他功能](#6.2 包装类具体的其他功能)


1、认识泛型

  • 定义类、接口、方法时、同时声明了一个或者多个类型变量(如:<E>)这样就被称为泛型类、泛型接口、泛型方法、它们统称为泛型。
  • 作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!
  • 好处:这样可以避免强制类型转换,以及可能出现的异常。
  • 泛型的本质 :把具体的数据类型作为参数传给类型变量

代码1:认识泛型,搞清楚泛型的好处

GenericDemo1类

java 复制代码
import java.util.ArrayList;

public class GenericDemo1 {
    public static void main(String[] args) {
        //目标:认识泛型、搞清楚泛型的好处
        //不使用泛型,这时候可以存储任意数据类型
        //不使用泛型在接收数据的时候,可能会出问题,存储的数据类型不固定
        ArrayList list = new ArrayList();
        list.add("hello");
        list.add("world");
        list.add("java");
        list.add(1);
        //String s =  list.get(0);  //报错
        Object s =  list.get(0);  //不报错
        //使用泛型,在接收数据时,会保证数据的类型安全
        //使用<String>list1只能添加字符串,如果添加其他类型报错
        ArrayList<String> list1 = new ArrayList<>(); //在JDK7后后面尖括号可以省略不写
        list1.add("hello");
        list1.add("world");
        //list1.add(10);//报错
        String s1 = list1.get(0);  //不报错
    }
}

2、泛型类

注意:类型变量建议用大写英文字母,常用的有E(一般代表数据类型)、T(一般代表返回值类型)、K、V(一般代表值类型)。

2.1 自定义泛型类

代码2:这里自定义了MyArrayList只是在学习泛型类的定义,并没有实现add等里面的方法。这里也可以给Java中的ArrayList包装给MyArrayList。包装设计模式

MyArrrayList类

java 复制代码
public class MyArrrayList <E>{
    Object[] array = new Object[10];
    public boolean add(E e){  //添加元素
        return true;
    }
}

GenericDemo2 类:用来测试代码

java 复制代码
public class GenericDemo2 {
    public static void main(String[] args) {
        //目标:自定义泛型类
        MyArrrayList list = new MyArrrayList();
        list.add(10);
        list.add("ll");

        MyArrrayList <String> list2 = new MyArrrayList<String>();
        list2.add("hello");
        //list2.add(11);  //报错
    }
}

上面的代码使用了泛型后只能添加相应的类型,如果加其他类型报错,报错信息如下:

3、泛型接口

3.1 自定义泛型接口

代码3:简单自定义泛型接口里面的具体方法并没有实现

Student类

java 复制代码
public class Student {
}

Teacher类

java 复制代码
public class Teacher {
}

data接口

java 复制代码
public interface data<T> {
    void add(T s);  //添加元素
    void remove(T s);  //删除元素
}

StudentData 类:接口的实现

java 复制代码
public class StudentData implements  data<Student>{

    @Override
    public void add(Student s) {
        System.out.println("添加学生数据成功");
    }

    @Override
    public void remove(Student s) {

    }
}

TeacherData 类

java 复制代码
public class TeacherData implements data<Teacher> {


    @Override
    public void add(Teacher s) {
    }

    @Override
    public void remove(Teacher s) {
    }
}

enericDemo3类

java 复制代码
public class GenericDemo3 {
    public static void main(String[] args) {
        //目标:搞清楚泛型接口的基本作用
        //需求:项目需要学生数据/老师数据都要进行增删改查操作
        StudentData s = new StudentData();
        s.add(new Student()); //添加学生数据

        TeacherData t = new TeacherData();
        t.add(new Teacher());  //添加老师数据
    }
}

4、泛型方法

代码4:

enericDemo4类

java 复制代码
public class enericDemo4 {
    public static void main(String[] args) {
        //目标:学会定义泛型方法,搞清楚作用。
        //打印任意数组的内容
        Integer[] intArr = {1, 2 , 3, 4 , 5};
        printArr(intArr);
        Character [] CharArr = {'a','b','v'};
        printArr(CharArr);
        String[] name = {"1", "hhh", "你好"};
        printArr(name);
    }
    public static <E>void printArr(E []arr){
        int len = arr.length;
        for(int i = 0; i < len; i++){
            System.out.print(arr[i]+ " ");
        }
        System.out.println();
    }
}
/*
1 2 3 4 5 
a b v 
1 hhh 你好 
 */

5、通配符、上下限

  • 就是"?",可以在**"使用泛型**"的时候代表一切类型:E T K V 是在定义泛型的时候使用。

泛型上下限:

泛型上限: ?extends Car : ?能接收的必须是Car或者其子类。

泛型下限: ? super Car: ?能接收的必须是Car或者其父类。

代码5:下面的代码只是写了个框架来理解通配符以及泛型上下限。

Car类

java 复制代码
//车类
//父类
public class Car {
}

XiaoMi类

java 复制代码
public class XiaoMi extends  Car{
}

BaoMa类

java 复制代码
public class BaoMa extends  Car{
}

Dog类

java 复制代码
public class Dog {
}

enericDemo5:测试1

java 复制代码
import java.util.ArrayList;

public class enericDemo5 {
    public static void main(String[] args) {
        //理解通配符和上下限
        ArrayList<Car> list = new ArrayList<>();
        list.add(new BaoMa());
        list.add(new XiaoMi());
        go(list);
    }
    //开发一个方法表示车要比赛,这里可能不同类型的车比
    public static void go(ArrayList<Car> c){
    }
}

enericDemo6 类:测试2

java 复制代码
import java.util.ArrayList;

public class enericDemo6 {
    public static void main(String[] args) {
        ArrayList<XiaoMi> list = new ArrayList<>();
        list.add(new XiaoMi());
        list.add(new XiaoMi());
        go( list);
        ArrayList<BaoMa> list2 = new ArrayList<>();
        list2.add(new BaoMa());
        list2.add(new BaoMa());
        go( list2);

        ArrayList<Dog> list3 = new ArrayList<>();
//        list3.add(new Dog());
//        list3.add(new Dog());
//        go(list3);
    }
    //如果这里要传入多种类型的参数
    //<>中写 XiaoMi,BaoMa、 Car 在调用时候都能会出问题
    //所以这里可以使用? 通配符<?>
    //表示这个方法可以接收任意类型的参数
    //那么问题来了,既然可以接收任意类型的参数。如果传入一个狗呢? 可以。但是狗没有不是Car,显然与现实不符
    //不能让狗和车比赛
    //所以引入了通配符的上限,下限
    public static void go(ArrayList<? extends Car> list){  //只有Car或者Car的子类才能调用这个方法
    }
    public static void go2(ArrayList<? super Car> list){  //只有Car或者Car的父类才能调用这个方法
    }
    public static void go3(ArrayList<?> list){  //任何类型都可以调用这个方法
    }
    public static void go4(ArrayList<XiaoMi> list){  //只有小米才能调用这个方法
    }
    public static void go5(ArrayList<BaoMa> list){  //只有宝马才能调用这个方法
    }

    //只有车才能调用这个方法 ,虽然XiaoMi和BaoMa都是Car的子类,但是ArrayList<XiaoMi> ArrayList<BaoMa>
    // 和 ArrayList<Car>没有关系的


    public static void go6(ArrayList<Car> list){  //只有车才能调用这个方法

    }
}

6、泛型支持的类型

  • 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)
  • 为什么泛型不支持基本数据类型? 泛型擦除:泛型工作在编译阶段,等编译后泛型就没有论了,所以泛型在编译后会被擦除。所以类型会恢复成Object类型。

代码7:泛型不支持基本数据类型

enericDemo7

java 复制代码
import java.util.ArrayList;

public class enericDemo7 {
    public static void main(String[] args) {
        //目标:搞清楚泛型集合不支持基本数据类型
        ArrayList<int> list = new ArrayList<>();  //报错
    }
}

6.1 包装类

包装类就是把基本类型的数据包装成对象的类型。

enericDemo8

java 复制代码
import java.util.ArrayList;

public class enericDemo8 {
    public static void main(String[] args) {
        //包装类
        //手工包装
        Integer i = new Integer(10);  //在JDk9 之后,被弃用
        Integer i1 = new Integer(10);
        System.out.println(i == i1);
        Integer i2 = Integer.valueOf(10);//推荐 -128 -127 之间的数字是被缓存的如果定义多个相同的变量,不会创建新的对象
        Integer i3 = Integer.valueOf(10);
        System.out.println(i2 == i3);  // true
        System.out.println(i == i3);  //false
        System.out.println("---------------自动装箱--------------");
        //自动包装、自动拆箱
        Integer i4 = 10;
        Integer i5 = 10;
        System.out.println(i4 == i5);

        Integer i6 = 128;
        Integer i7 = 128;
        System.out.println(i6 == i7);

        System.out.println("---------------自动拆箱--------------");
        //把包装类对象转换为对应的原始数据类型
        int i8 = i4;
        System.out.println(i8);

        ArrayList<Integer> list = new ArrayList<>();
        list.add(10);  //自动装箱
        int i9 = list.get(0);  //自动拆箱
    }
}
/*
false
true
false
---------------自动装箱--------------
true
false
---------------自动拆箱--------------
10
 */

6.2 包装类具体的其他功能

代码9:

java 复制代码
public class enericDemo9 {
    public static void main(String[] args) {
        //包装类的基本功能
        //把基本类型转为字符串
        //方法一
        int a = 10;
        String s = a + "";
        System.out.println(s);

        //方法二
        double b = 10.3;
        String str = Double.toString(b);
        System.out.println( str);

        //方法3:
        Integer i = new Integer(10);
        String s1 = i.toString();
        System.out.println(s1);

        System.out.println("------把字符串转化为真实类型------");

        //方法一
        String s2 = "10";
        int a1 = Integer.parseInt(s2);
        System.out.println(a1 + 1);
        //方法二
        String s3 = "10.1";
        double a2 = Double.valueOf(s3);
        System.out.println(a2 + 1);
    }
}
/*
10
10.3
10
------把字符串转化为真实类型------
11
11.1
 */
相关推荐
Dev7z1 分钟前
让阅卷不再繁琐:图像识别与数据分析提升智能答题卡评分效率
人工智能·计算机视觉
tuokuac1 分钟前
Maven中的属性占位符的用法
java·maven
咚咚王者2 分钟前
人工智能之数据分析 numpy:第十一章 字符串与字节交换
人工智能·数据分析·numpy
芒克芒克4 分钟前
Maven 项目管理从入门到进阶:基础与高级实战全解析
java·maven
郝学胜-神的一滴2 小时前
Qt的QSlider控件详解:从API到样式美化
开发语言·c++·qt·程序人生
学困昇2 小时前
C++11中的{}与std::initializer_list
开发语言·c++·c++11
郝学胜-神的一滴3 小时前
Qt的QComboBox控件详解:从API到样式定制
开发语言·c++·qt·程序人生·个人开发
憧憬blog3 小时前
【Kiro开发集训营】拒绝“屎山”堆积:在 Kiro 中重构“需求-代码”的血缘关系
java·开发语言·kiro
数字孪生家族3 小时前
视频孪生与空间智能:重构数字时空认知,定义智能决策新范式
人工智能·重构·空间智能·视频孪生与空间智能
e***74953 小时前
Spring Security 官网文档学习
java·学习·spring