IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【浅学Java】一篇文章带你走进Java泛型的世界 -> 正文阅读

[Java知识库]【浅学Java】一篇文章带你走进Java泛型的世界

1. 什么是泛型?

泛型就是适用于许多许多类型。从代码上讲就是对类型实现了参数化。(听完这句话,是不是很懵,不着急,我们接着往下看)

2. 引出泛型

下面,我们来思考一个问题:

如何实现一个类,类中包含数组成员,使得数组中能够存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值?

这个问题的突破口在哪?思索一番,想起一句话:所有类的父类,默认为Object类。那我们不妨用Object来接收各种各种的数据类型:

首先,我们来实现一下这个数组:

class MyArray{
    public Object []array=new Object[10];
}

接下来,我们考虑一下如何根据成员方法返回数组中某个下标的值?

class MyArray{
    public Object []array=new Object[10];
    public Object getValue(int pos){
        return this.array[pos];
    }
    public void setValue(int pos,Object val){
        this.array[pos]=val;
    }
}
public class Test1 {
    public static void main(String[] args) {
        MyArray myArray=new MyArray();
        myArray.setValue(0,"bit");
        myArray.setValue(1,12);
        myArray.setValue(2,0.987);
        String a=(String)myArray.getValue(0);
        int b=(int)myArray.getValue(1);
        double c=(double)myArray.getValue(2);
    }
}

上面的代码确实已经实现了我们想要的效果,但是在主函数中接收数组中的元素时,我们好像无法避免的去强制类型转换 myArray.getValue(pos) 的返回值,这是一种非常不可取的方式,因为当你不知道数组中某个下标的元素的元素类型时,就无法拿到想要的结果。

因此,在实际运用当中,我们还是更多的希望该数组持有一种数据类型,而不是同时持有多种数据类型。所以,泛型由此而生。

泛型的主要作用目的:就是指定当前的容器,要持有什么类型的对象。让编译器去检查。此时,就需要把类型,作为参数传递。需要什么类型,就传入什么类型。

3. 泛型的语法

先来看一个代码分析:
在这里插入图片描述

上面的代码:
MyArray< String> myArray=new MyArray<>() 传String类型给MyArray类,MyArray类通过< T>接收,这就是泛型运用的基本语法。

几个注意事项:

  1. < >里面必须是引用类型。所以所有的基础数据类型必须使用包装类。
  2. 泛型帮我们在编译期间做了2件事情:存放元素的时候,进行类型的检查;取元素的时候,帮我进行类型的转换

4. 泛型小结:

  1. 泛型是将数据类型参数化,进行传递
  2. 使用 表示当前类是一个泛型类。
  3. 泛型目前为止的优点:数据类型参数化,编译时自动进行类型检查和转换

5. 泛型是如何编译的?

在编译的过程当中,将所有的T替换为Object这种机制,我们称为:擦除机制

由于知识储备有限,先不做分享。

6. 泛型的上界

示例1:

public class MyArray<E extends Number> {
...
}

只接收Number及Number的子类作为E的类型实参

示例2:

//写一个泛型类,类中有一个方法,求数组的最大值
class Alg<T extends Comparable<T>>{
    public T finMax(T[] array){
        T max =array[0];
        for(int i=1;i<array.length;i++){
            if(max.compareTo(array[i])<0){
                max=array[i];
            }
        }
        return max;
    }
}
class Student implements Comparable<Student>{
    public int age;
    public String name;

    @Override
    public int compareTo(Student o) {
        return this.age-o.age;
    }
}
public class test {
    public static void main(String[] args) {
        Alg<Student> alg=new Alg<>();
        Student []array= new Student[10];
        Student max=alg.finMax(array);
        System.out.println(max);
    }
}

在这里插入图片描述
注意:泛型是没有下界的。

7. 泛型方法

class Util {
    //静态的泛型方法 需要在static后用<>声明泛型类型参数
    public static <E> void swap(E[] array, int i, int j) {
        E t = array[i];
        array[i] = array[j];
        array[j] = t;
    }
}

在调用静态的泛型方法时,是不需要进行实例化的。

8. 通配符

在这里插入图片描述
站在fun函数的角度,他并不知道传入Message的具体类型的,所以他不能写入数据。

通配符的上界

<? extends 上界>
<? extends Number>//可以传入的实参类型是Number或者Number的子类

通配符的上界,不能进行写入数据,只能进行读取数据

通配符的下界

<? super 下界>
<? super Integer>//代表 可以传入的实参的类型是Integer或者Integer的父类类型

通配符的下界,不能进行读取数据,只能写入数据。

9. 包装类

在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型。

9.1 基本数据类型和对应的包装类

在这里插入图片描述

9.2 装箱和拆箱

装箱:

public static void main(String[] args) {
        int a=10;
        Integer b=a;//自动装箱————底层默认调用valueOf
        Integer d=Integer.valueOf(a);//手动装箱
        System.out.println();
    }

拆箱:

public static void main(String[] args) {
        Integer a=10;
        int b=a;//自动拆箱
        double d=a;//自动拆箱,默认都是用intValue()拆箱,先拆成int类型数据,再进行转换
        double d2=a.doubleValue();//手动拆箱
    }

9.3 一道例题

在这里插入图片描述
为什么会发生这种情况?

在自动装箱过程中,会默认调用valueOf( ) 函数,该函数的原码分析如下:
在这里插入图片描述
所以,在比较包装类的大小时,不要用==,而采用equals方法。示例如下:
在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-26 11:28:38  更:2022-04-26 11:33:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:28:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码