一文带领大家了解什么是泛型

news2024/11/20 18:43:02

对于泛型!其实大家了解不是很多,在各大高校的学习中,如果你不去深入的了解泛型,老师只是会一水儿过,并不会单独去带领大家了解!!那么,笔者结合自身的学习泛型的想法,结合了一些课件,索性写出了一篇关于泛型的简单博客,来带领大家了解泛型!!

一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的 代码,这种刻板的限制对代码的束缚就会很大。

                                                                            ----- 来源《Java编程思想》对泛型的介绍。

简而言之,泛型:就是适用于许多许多类型,从代码上讲,就是对类型实现参数化!

在Java语法中,泛型是一个较难的语法,但是,在目前这个博客中,笔者仅仅讲解一部分,目前所接触的只是一丢丢!!后续在数据结构进阶阶段将会深入了解泛型!!

引出泛型??

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

解题思路:

  1. 我们之前学过的数组,只能存放指定类型的元素!
    int[] array = new int[10];
    String[] strs = new String[10];
  2. 所有类的父类默认为Object类,数组是否可以创建为Object类??

 下面请看笔者根据上面两个思路所进行书写的代码:

 


class MyArray {
    public Object[] obj = new Object[3];
    
    public Object getPos(int pos) {
        return obj[pos];
    }//返回所对应的pos下标的值
    
    public void setObj(int pos , Object val) {
        obj[pos] = val;
    }//将数组下标为pos的元素赋值为val
}

public class Test {
    public static void main(String[] args) {
      MyArray myArray = new MyArray();
      
      myArray.setObj(0,10);//存放整型
        myArray.setObj(1,"hello"); //存放字符串
        myArray.setObj(2,10.56); //存放double类型 
        //实现了存储任意类型的数据!
    }
}

对于上述代码,实现了一个数组,并且该数组内部可以存放任何数据,但是,当我们想要打印该数组中的某下标的值时,列如: double d = myArray.getPos(2); 这样写会进行报错!!

d1e920842cc54a0f870f9e5af585e677.png

当我们进行强制类型转化的时候,double d = (double) myArray.getPos(2); 不会进行报错了!!

b3c9e4570c3c4915ad55f620784c08a5.png

那么疑问又来了,笔者现在定义的数组很小,我们可以看到数组里面存储的数据类型,但是,当我们定义一个很大很大的数组时,当输出某一元素的时候,又怎能知道该下标所对应的元素类型呢??

上述代码实现后,我们可以发现:

  1. 任何类型的数据都可以存放
  2. 获取数据的时候(double d = myArray.getPos(2) ),编译报错,必须进行强制类型转化

虽然在这种情况下,当前数组任何数据都可以存储,但是,更多情况下,我们还是希望他只能持有一种数据类型,而不是同时持有这么多的类型,所以,泛型,的主要目的,就是指定当前的容器,要 持有什么类型的对象,让编译器去做检查,此时,就需要把类型作为参数进行传递,需要什么类型,就传入什么类型!

下面请看笔者的简单的代码:


class MyArray<T> {
    //public Object[] obj = new Object[3];
    
    public T[] obj = (T[])new Object[3];
    //先这样理解,会有警告
    //在Java官方不会这样去写

    public T getPos(int pos) {
        return obj[pos];
    }//返回所对应的pos下标的值

    public void setObj(int pos , T val) {
        obj[pos] = val;
    }//将数组下标为pos的元素赋值为val
}

public class Test {
    public static void main(String[] args) {
        MyArray<Integer> myArray = new MyArray<Integer>();
        //实列化对象的同时,指定当前泛型类的指定参数类型是Integer
        //然后就可以进行存储指定的数据类型
        
        myArray.setObj(0,10);
        myArray.setObj(1,78);
        myArray.setObj(2,99);
        //myArray.setObj(0,"sjd");//传入不是整型的数据,会进行报错
        
        Integer d = myArray.getPos(2);  //不需要强制类型转化
    }
}

对于上述代码,便是泛型的简单应用,如果您能看懂上述的代码,那么,恭喜你,对于泛型的简单应用,你已经学会了!!

对于泛型,有着下面几个简单的意义:

  1. 存储数据的时候,可以帮助我们进行自动的类型检查
  2. 获取元素的时候,可以帮助我们进行类型转化

上述的两点意义,是在编译的时候,就进行的,因此,泛型是编译时期的一种机制,在运行的时候,没有泛型的概念!!

下面来带领大家走进泛型的语法!!

语法1:

语法1:

 class 泛型类名称 <类型形参列表> {

// 这里可以使用类型参数

}

语法1 的使用情况为

class ClassName<T1,T2,T3…………Tn> {

…………

}

语法2:

语法2:

class 泛型类名称 <类型形参列表> extends 继承类/* 这里可以使用类型参数 */

{

// 这里可以使用类型参数

}

 

class ClassName<T1,T2,T3…………Tn> extends ParentClass<T1> {

// 可以只使用部分类型参数

}

 

对于上述的类名后的<T> 代表占位符,表示当前类是一个泛型类!!

了解一下: ;类型形参一般使用一个大写字母表示,常用的占位符有:

  1. E   表示:Element
  2. K   表示:Key
  3. V   表示:Value
  4. N   表示:Number
  5. T   表示:Type
  6. S,U,V等等,第二,第三,第四个类型

在上述占位符中,E , K , V , T 所应用的比较多!!谨记,其实对于上述的用法,笔者也……尴尬了!

值得注意的是:不可以new 一个泛型类型的数组(语法规定)比如:public T[] obj = new T[3]; 这个就是一个错误的做法!因此,泛型当中,不能实列化一个泛型类型的数组!!!

小结一下,瞬间开心:

  1. 泛型是将数据类型参数化进行传递
    MyArray<Integer> myArray = new MyArray<Integer>();
    
  2. 使用<T>,表示当前类是一个泛型类
  3. 泛型目前为止的优点:数据类型参数化,编译时自动进行检查和转化
  4. 运行的时候,没有泛型的概念,编译完成之后,泛型被擦除为Object(擦除机制仅作了解即可)

在Java的泛型机制是在编译级别实现的,编译器生成的字节码在运行的期间,并不包含泛型的类型信息

下面笔者就Java当中,泛型的正确写法,来简单书写一下:(以后将会经常使用)Java官方的写法!

    public Object[] obj = new Object[3];

    public E getPos(int pos) {
         return (E)obj[pos];
    }

 对于上述代码的简单解析:

c8d316104e2e4e9eaaaa747e7515c6bc.png

 上面笔者简单的介绍了一下泛型,那么,就用泛型来实现一个小小的练习题吧!!

实现一个泛型,泛型类里面写一个方法,来求得数组的最大值??

 对于这个方法,我们可以根据最原始的:求数组的最大值的代码,来进行简单改写,然后改编成为我们想要的代码!

抛开泛型,我们在以前在数组中寻找最大值的代码为:

//抛开泛型,我们在以前在数组中寻找最大值的代码为:
class Alg{
    public int findMax(int[] array) {
        int max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (max < array[i]) {
                max = array[i];
            }
        }
        return max;
    }
}

对于上述代码,想必,到目前为止,大家已经了然于胸了吧!!不用在进行讲解了!!

那么,笔者就根据上述的代码进行简单改写一下,然后就出现我们想要的泛型写法了!!请大家仔细对比一下哟!

class Alg<E extends Comparable<E>>{
    public E findMax(E[] array) {
        E max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (max.compareTo(array[i]) < 0) {
                max = array[i];
            }
        }
        return max;
    }
}
public class Test2 {
    public static void main(String[] args) {
        Alg<Integer> alg = new Alg<>();
        Integer[] array = {1,4,7,29,20,48,21,23};
        Integer val =alg.findMax(array);
        System.out.println(val);
    }
}

上述代码,便是用泛型来实现要求!!代码的运行结果为:

115311330f1b430aa92c7b6f75ead7f7.png

简单解析一下吧!:

ed08147d7b27431893c70ef137f3594c.png

上述代码是一个泛型类,那么有没有泛型方法呢??那么,请看笔者下面的代码吧!来带领大家用泛型方法来实现一下题目需求!!

//泛型方法
class Alg{
    public <E extends Comparable<E>> E findMax(E[] array) {
        E max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (max.compareTo(array[i]) < 0) {
                max = array[i];
            }
        }
        return max;
    }
}
public class Test2 {
    public static void main(String[] args) {
       Alg alg = new Alg();
        Integer[] array = {1,4,7,29,20,48,21,23};
        Integer val =alg.findMax(array);
        System.out.println(val);
    }
}

上述的代码,就是用泛型方法来实现,求得数组中的最大值

代码的运行结果也是正确的!!

99940a4b327f45cdbc9d6598bbd22828.png

 对于这个方法,必须通过对象的引用才能调用!!

思考一下,如果我们不想通过对象的引用,那么我们应该怎么办??

很简单,将其改为静态(static)修饰的的不就行了吗??

请看笔者代码:

//泛型的静态方法
class Alg{
    public static  <E extends Comparable<E>> E findMax(E[] array) {
        E max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (max.compareTo(array[i]) < 0) {
                max = array[i];
            }
        }
        return max;
    }
}
public class Test2 {
    public static void main(String[] args) {
        Integer[] array = {1,4,7,29,20,48,21,23};
        Integer val =Alg.findMax(array);
        System.out.println(val);
    }
}

上述代码,就是用静态(static)来修饰的!!

静态方法不依赖于对象,可以通过类名进行访问!!

对于此篇博客,有不懂的各位老铁,欢迎来咨询

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/76853.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2022年双十二拼多多百亿补贴有活动吗?如何领红包?

2022年双十二拼多多百亿补贴有活动吗?如何领红包? 拼多多的活动大家都很清楚&#xff0c;平常没有活动的时候&#xff0c;价格也是比较实惠的&#xff0c;除了拼团购物之外&#xff0c;拼多多还有百亿补贴&#xff0c;所以商品比其他平台都要便宜&#xff0c;双十二拼多多百亿…

物理数据库服务器扫描hba卡识别共享磁盘命令

1、问题背景 默认情况&#xff0c;在扩容完1套物理rac共享存储后&#xff0c;rac主机是不能识别共享存储的。那么该怎么办呢&#xff1f; 2、解决办法 例如&#xff0c;在扩容完1套物理rac共享存储后&#xff0c;如果rac主机不能识别共享存储的话(一般需要执行命令后&#x…

Jboss弱口令Getshell

文章目录漏洞简介影响版本环境搭建漏洞复现漏洞简介 JBoss Administration Console存在默认账号密码admin/vulhub&#xff0c;如果Administration Console可以登录&#xff0c;就可以在后台部署war包getshell 影响版本 Jboss4.x及其之前的版本 console 管理路径为/jmx-consol…

day16【代码随想录】反转字符串、反转字符串中的元音字母、反转字符串||、反转字符串中的单词|||、替换空格、翻转字符串中的单词、左旋转字符串

文章目录一、反转字符串&#xff08;力扣344&#xff09;二、反转字符串中的元音字母&#xff08;力扣345&#xff09;三、反转字符串 II&#xff08;力扣541&#xff09;四、反转字符串中的单词 III&#xff08;力扣557&#xff09;五、替换空格&#xff08;剑指 Offer 05&…

Kubernetes ~ k8s 从入门到入坑。

Kubernetes ~ k8s 从入门到入坑。 文章目录Kubernetes ~ k8s 从入门到入坑。1. Kubernetes 介绍。1.1 应用部署方式演变。1.2 kubernetes 简介。1.3 kubernetes 组件。1.4 kubernetes 概念。2. kubernetes 集群环境搭建。2.1 前置知识点。2.2 kubeadm 部署方式介绍。2.3 安装要…

人工智能前沿——玩转OpenAI聊天机器人ChatGPT(免费中文版)

目录 2022 地表最强AI聊天机器人ChatGPT诞生&#xff01;&#xff01;&#xff01; 一、前言 &#x1f384;&#x1f388; ChatGPT是OpenAI开发的一个大型预训练语言模型。它是GPT-3模型的变体&#xff0c;GPT-3经过训练&#xff0c;可以在对话中生成类似人类的文本响应。Cha…

Vite + Vue3 项目中,使用 vw/vh 适配移动端,并通过 Android Studio 打包

目录 1. 使用 vw/vh 适配移动端 1.1 使用 vite 初始化项目 1.2 安装插件&#xff0c;将 px 转化成 vw 1.2.1 在 vite.config.ts 中&#xff0c;声明插件 1.2.2 手写 postcss 类型声明文件&#xff0c;解决 路径爆红、没有提示 1.2.3 tsconfig.config.json VS tsconfig.js…

Java 8 Stream 之 collect() 的奇技淫巧!

前言 本身我是一个比较偏向少使用Stream的人&#xff0c;因为调试比较不方便。 但是, 不得不说&#xff0c;stream确实会给我们编码带来便捷。 所以还是忍不住想分享一些奇技淫巧。 正文 Stream流 其实操作分三大块 &#xff1a; 创建 处理 收集 我今天想分享的是 收集…

核心内参:S参数的三个重要特性——因果性、无源性与互异性

1 从一个报错开始 S参数在射频、高速领域的应用非常广泛&#xff0c;相关知识点也非常多。最近浏览了一本2020年新出版的书《S Parameter for Signal Integrity》&#xff0c;作者是IEEE Fellow、业界大牛Peter J. Pupalaikis&#xff0c;现任职于Teledyne LeCroy。该书写的非…

《Linux运维实战:使用Percona Backup for MongoDB备份与恢复Mongodb数据》

一、备份与恢复方案 Percona Backup for MongoDB 是一个开源、分布式和低影响的解决方案&#xff0c;用于MongoDB分片集群和副本集的一致备份。从版本1.7.0开始&#xff0c;Percona Backup for MongoDB支持物理和逻辑备份和恢复&#xff0c;仅支持对逻辑备份进行时间点恢复。 …

linux支持ipv6

1. kernel config [*] Networking support ---> Networking options ---> <*> The IPv6 protocol ---> 2. test 2.1 /proc/net/if_inet6 查看/proc/net/if_inet6文件是否存在以确定你的系统是否支持IPv6。 如果没有&#xff0c;可尝试如下命令加载IPv6模…

磺化氰化物7酪胺Sulfo-Cy7 TSA,Sulfo-Cyanine7 TSA,Sulfo-Cyanine7 Tyramide

Sulfo-Cyanine7 Tyramide&#xff0c;Sulfo-Cy7 TSA&#xff0c;Sulfo-Cyanine7 TSA&#xff0c;磺酸基-花青素Cy7 酪酰胺产品结构&#xff1a; 产品规格&#xff1a; 1.Packaging specification&#xff1a;5mg, 10mg, 25mg, flexible packaging, including 100mg packaging a…

11.AOP之注解配置

1.使用IDEA创建工程 2.引入项目使用的依赖 <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.2.RELEASE</version></dependency><depend…

一、计算机网络体系结构(一)计算机网络概述

目录 1.1计算机网络的概念、组成与功能 1.2计算机网络的分类 1.2.1按分布范围分类 1.2.2按传输技术分类 1.2.3按拓扑结构分类 1.2.4按使用者分类 1.2.5按交换技术分类 1.2.6按传输介质分类 1.3计算机网络的主要性能指标 1.1计算机网络的概念、组成与功能 计算机网络的…

PHP单商户视频号对接流程

一、序关联至对应视频号&#xff0c;并在视频号带货直播中使用。 首先&#xff0c;商家需要在微信后台申请自定义版交易组件权限&#xff0c;申请成功后&#xff0c;可以将小程 二、申请开通商户号 等商户号审核之后在操作一下步骤接口调用&#xff08;pro为例&#xff09; 实…

k8s ~ 数据存储、安全认证、DashBoard。

k8s ~ 数据存储。 文章目录k8s ~ 数据存储。8.1 基本存储。8.1.1 EmptyDir。8.1.2 HostPath。8.1.3 NFS。8.2 高级存储。8.2.1 PV。8.2.2 PVC。8.2.3 生命周期。8.3 配置存储。8.3.1 ConfigMap。8.3.2 Secret。9. 安全认证。9.1 访问控制概述。9.2 认证管理9.3 授权管理。9.4 准…

Flink窗口(Flink Window)

上一篇flink watermark讲到Flink 中事件时间和水位线的概念&#xff0c;那它们有什么具体应用呢&#xff1f;当然是做基于时间的处理计算了。其中最常见的场景&#xff0c;就是窗口聚合计算。 之前我们已经了解了 Flink 中基本的聚合操作。在流处理中&#xff0c;我们往…

Neo4j的Java API操作

Neo4j的Java API操作 文章目录Neo4j的Java API操作0. 写在前面1、前置芝士2. 准备工作2.1 为项目引入Neo4j依赖2.2 启动和停止3、Java操作Neo4j4、参考资料0. 写在前面 Linux版本&#xff1a;Ubuntu Kylin 16.04Neo4j版本&#xff1a;Neo4j-3.2.7 CommunityProject Build Tool…

微服务链路追踪SkyWalking(9.2.0)

微服务链路追踪SkyWalking(9.2.0) 链路追踪介绍 对于一个大型的几十个、几百个微服务构成的微服务架构系统&#xff0c;通常会遇到下面一些问题&#xff0c;比如&#xff1a; 如何串联整个调用链路&#xff0c;快速定位问题&#xff1f;如何缕清各个微服务之间的依赖关系&am…

m基于FPGA的GPS收发系统开发,包括码同步,载波同步,早迟门跟踪环,其中L1采用QPSK,L2采用BPSK

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 最早的GPS包含L1和L2两个频段&#xff0c;其中L1上调制CA码&#xff0c;P码以及导航电文&#xff0c;L2上调制P码和导航电文。在实际接收到的GPS信号中&#xff0c;我们除了能够接受到CA码和P码外…