简单了解泛型

news2024/11/25 20:50:46

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

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

简单来说就是让基本数据类型也能面向对象.基本数据类型可以使用很多方法, 这就必须让它变成类.

基本数据类型对定的包装类

基本数据类型       包装类

byte                      Byte

short                    Short

int                        Integer

long                     Long

float                     Float

double                 Double

char                    Character

boolean              Boolean

除了Integer 和 Character ,其余基本类型的包装类都是首字母大写

装包(箱)和拆包(箱)

把基本类型变为包装类型, 叫做装箱

把包装类型变为基本类型, 叫做拆箱

    public static void main(String[] args) {
        //自动装包, 内部其实是调用了 valueOf 方法来实现的
        Integer a = 10;
        int i = 99;
        Integer b = i;
        //基本类型 转变为 包装类型, 都是可以直接打印的
        System.out.println(a);
        System.out.println(b);
        //显示装箱
        Integer aa = Integer.valueOf(10);
    }
    public static void main(String[] args) {
        Integer a = 10;
        //自动拆箱, 内部调用了 intValue() 方法;
        int i = a;
        //拆包
        int aa = a.intValue();
        double b = a.doubleValue();
    }

Java 包装类提供了很多方法, 可以自动调用很方便

    public static void main(String[] args) {
        Integer a = 100;
        Integer b = 100;
        System.out.println(a == b);

        Integer a1 = 200;
        Integer b1 = 200;
        System.out.println(a1 == b1);
    }
    //代码上述的输出结果为: true   和    false

为什么呢?

如果出现这个错误第一时间想到了什么呢? 我想可以看一下 Integer 出现了什么错误, 然后呢? 在赋值的过程中出现了自动装箱, 自动装箱的函数是 valueOf , 所以可以在valueOf中寻找出错的点在哪里, 现在找到 valueOf 的源码, 看装包的过程哪一点出错了

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

这个源码, 如果 i 在范围内就返回一个数组里面的值, 如果不在范围就返回 new Integer(i)

我们在源码中可以得到 low的大小为 -128, high 的大小为 127;

也就是 i 的范围在 -128 到 127 之间的话返回这个数组的某一个值

这个数组大小是多少呢? 范围是 [-128, 127], 共 256 个数字, 可以得出 下图 这个数组的样子

当 i 的范围在其之间可以返回相同的值, 如果超过了就返回一个 new 的值. 由此可出上述结果为什么是这样.

泛型

是Java中一种很难的语法

举个例子, 写一个类, 类包含一个数组成员, 让数组中可以存放任意类型的数据, 也能根据成员方法返回数组某个下标的值.

class MyArray {
    Object[] array = new Object[10];
    void setValue(int i, Object val) {
        array[i] = val;
    }
    Object getValue(int i) {
        return array[i];
    }
}
public class Main {
    public static void main(String[] args) {
        MyArray myArray = new MyArray();
        myArray.setValue(0, 1);
        myArray.setValue(1, "hello");
        //下面这一行代码报错, 因为返回值是 Object 类型,
        //需要强转为 String 类型才可以
        //String str = myArray.getValue(0);  <---报错
        String str = (String)myArray.getVlaue(0);
    }
}

这我们就想了, 不能让什么数据类型都能放到这个数组中, 我们可以指定一个数据, 这样我们在接受数据的时候也不用看每一个接收的数据是什么类型了. 我们就引入了泛型.

泛型的语法

1>

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

    //可以使用类型参数

}

示例:

class ClassName<T1, T2, .... Tn>{

}

2>

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

         //可以使用类型参数

}

示例:

class ClassName<T1, T2, .... Tn> extends ParentClass<T1> {

        //可以使用类型参数

}

类型形参列表可以用 T , E , K , V 等字母表示 其中<T, E, K, V...> 表示什么呢?

表示当前类 是一个泛型类 它只是一个占位符.

下面将上述代码改一下:

class MyArray <T>{
    Object[] array = new Object[10];
    void setValue(int i, T val) {
        array[i] = val;
    }
    T getValue(int i) {
        return (T)array[i]; // 把返回的类型,强转为指定类型
    }
}
public class Main {
    public static void main(String[] args) {
        //这行代码强制了数据类型为Integer, <>里面只能放入包装类
        MyArray<Integer> myArray = new MyArray<>();
        myArray.setValue(0, 1);
        //myArray.setValue(1, "hello");  <----当前代码报错了
        //如果我们想要放入其它类型的数据怎么做呢? 在创建一个新对象就好了
        MyArray<String> myArray1 = new MyArray<>();
        int i = myArray.getValue(0);
        System.out.println(i);
    }
}

 注意:

1> 因为使用了泛型, 在编译的时候 帮我们进行了类型的检查, 取数据也不需要进行类型转换

2> 在尖括号 <> 里面必须是引用类型.

3> 创建的一个数组的时候 不能写成 T[] array = new T[];

泛型的上界

语法:

class 泛型类名称  <类型形参 extends 类型边界>{

...

}

示例:

public class MyArray<T extends Number> {

...

}

其中的 T 必须是 Number 或者 Number的子类, 这就叫做泛型的上界

在创建对象时:

MyArray<Integer> a1 = new MyArray<>();   可以

MyArray<Double> a1 = new MyArray<>();   可以

MyArray<String> a1 = new MyArray<>();   不可以

举例: 写一个泛型类, 求一个数组中的最大值

class Alg<T> {
    public T findMaxValue(T[] array) {
        T max = array[0];
        for (int i = 1; i < array.length; i++) {
            if(max < array[i]) {
                max = array[i];
            }
        }
        return max;
    }
}

这段代码的 if 中的判断条件会出现报错, 为什么呢?

因为 T 是引用数据类型, 最终是被擦除为了 Object 类型, Object 没有实现了Comparable 接口, 所以不能直接比较大小, 要想能够比较大小, 就得让 T 实现 Comparable 接口, 实现了 Comparable接口后, 以后创建对象时, 只有实现了 Comparable 接口的才能创建

就比如: 

MyArray<Integer> a1 = new MyArray<>();   可以, 因为Integer 实现 Comparable 接口

class Preson { ... }

MyArray<Person> a1 = new MyArray<>();   不可以 , 因为Person 没有实现 Comparable 接口

所以上述代码应该写成:

class Alg<T extends Comparable> {
    public T findMaxValue(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;
    }
}
public class Main {
    public static void main(String[] args) {
        Alg<Integer> alg = new Alg<>();
        Integer[] integers = {1, 2, 3, 4, 5, 6};
        Integer ret = alg.findMaxValue(integers);
        System.out.println(ret);
    }
}

写一个泛型方法:

如下列代码:

在这种情况下会出现 类型推导, 根据实参传值, 来推导出此时的类型.

class Alg2 {
    public <T extends Comparable>T findMaxValue(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;
    }
}
public class Main {
    public static void main(String[] args) {
        Alg2 alg2 = new Alg2();
        Integer[] integers = {1, 2, 3, 4, 5, 6};
        Integer ret2 = alg2.findMaxValue(integers);
        System.out.println(ret2);
    }
}

下列代码将泛型方法改为静态的, 可以通过类名直接调用该泛型方法, 不用实例化对象了

class Alg3 {
    public static <T extends Comparable>T findMaxValue(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;
    }
}

public class Main {
    public static void main(String[] args) {
        Integer[] integers = {1, 2, 3, 4, 5, 6};
        Integer ret3 = Alg3.findMaxValue(integers);
        System.out.println(ret3);
    }
}

小结

学会泛型的含义, 泛型的目的, 泛型的语法

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

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

相关文章

Istio 流量管理(请求路由、流量转移、请求重试、流量镜像、故障注入、熔断等)介绍及使用

一、Istio 流量管理 Istio是一个开源的服务网格&#xff0c;它为分布式微服务架构提供了网络层的抽象。它使得服务之间的通信变得更为可靠、安全&#xff0c;并且提供了细粒度的流量管理、监控和策略实施功能。Istio通过在服务之间插入一个透明的代理&#xff08;Envoy&#x…

Unreal游戏GPU参数详解,游戏性能优化再升级

UWA GOT Online For Unreal GPU模式近期全新发布&#xff0c;方便开发者从渲染和带宽的角度进行GPU分析。同时&#xff0c;此次更新中UWA也增加了丰富的GPU参数&#xff0c;涵盖了GPU SoC和GPU Counter模块。这些新增的参数不仅能够帮助Unreal开发者从宏观层面监控GPU的压力状况…

QT-TCP通信

网上的资料太过于书面化&#xff0c;所以看起来有的让人云里雾里&#xff0c;看不懂C-tcpsockt和S-tcpsocket的关系 所以我稍微画了一下草图帮助大家理解两个套接字之间的关系。字迹有的飘逸勉强看看 下面是代码 服务端&#xff1a; MainWindow::MainWindow(QWidget *parent) …

Jira Server 不维护了,如何将 Jira 平滑迁移到阿里云云效

作者&#xff1a;天彤 Atlassian 在 2020 年官方发布公告&#xff0c;从 2021 年起停止 Jira Server 产品的销售&#xff0c;并且在 2024 年彻底停止 Server 端产品的服务支持&#xff0c;这对于国内使用 Jira 产品的企业和研发团队造成了不小的影响。而此时国内很多 DevOps 产…

本地主机访问服务器的Redis -- 配置 ssh 端口转发

前言 在进行Java开发时&#xff0c;高度的依赖 Windows 上的开发软件 idea &#xff0c;那么我们想访问位于服务器上的 redis 怎么办呢&#xff1f;在平时我们想访问位于服务器上的程序&#xff0c;只需要开放它的端口即可&#xff0c;比如我们创建的网站&#xff0c;比如 tomc…

【拆位法 决策包容性 位运算】2871. 将数组分割成最多数目的子数组

本文涉及知识点 拆位法 贪心 位运算 决策包容性 位运算、状态压缩、子集状态压缩汇总 LeetCode2871. 将数组分割成最多数目的子数组 给你一个只包含 非负 整数的数组 nums 。 我们定义满足 l < r 的子数组 nums[l…r] 的分数为 nums[l] AND nums[l 1] AND … AND nums[r…

使用图网络和视频嵌入预测物理场

文章目录 一、说明二、为什么要预测&#xff1f;三、流体动力学模拟的可视化四、DeepMind神经网络建模五、图形编码六、图形处理器七、图形解码器八、具有不同弹簧常数的轨迹可视化九、预测的物理编码和推出轨迹 一、说明 这是一篇国外流体力学专家在可视化流体物理属性的设计…

如何使用vue脚手架创建项目

前言 使用vue搭建项目的时候&#xff0c;我们可以通过对应的cmd命令去打开脚手架&#xff0c;然后自己配置对应的功能插件 说明&#xff1a; 要使用Vue脚手架创建项目&#xff0c;你需要先确保你已经安装了Node.js和npm&#xff08;Node.js的包管理器&#xff09;。然后&#…

Github 2024-05-07 开源项目日报 Tp10

根据Github Trendings的统计,今日(2024-05-07统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量TypeScript项目4Jupyter Notebook项目2Python项目1Batchfile项目1非开发语言项目1Java项目1HTML项目1C#项目1从零开始构建你喜爱的技术 创建周期…

性能测试基础介绍

1.性能测试的意义 1.1.现状 互联网行业发展快&#xff0c;用户量大大增加&#xff1b; 业务和系统架构越来越复杂&#xff0c;数据越来越多&#xff0c;用户不仅仅满足于功能的实现&#xff0c;在某些场景下&#xff0c;更 在意系统性能。 1.2.什么是性能测试 通过一定的手段&…

Google准备好了吗?OpenAI发布ChatGPT驱动搜索引擎|TodayAI

在科技界波澜壮阔的发展中&#xff0c;OpenAI正式宣布其最新突破——一个全新的基于ChatGPT技术的搜索引擎&#xff0c;旨在直接挑战谷歌在搜索领域的统治地位。这一创新将可能彻底改变用户上网搜索的方式。 据悉&#xff0c;这款AI驱动的搜索引擎利用了ChatGPT的强大功能&…

快速搭建linux虚拟机环境

1、虚拟机资源 VMwareWorkstation&#xff1a;Download VMware Workstation Pro virtualbox&#xff1a;Oracle VM VirtualBox 2、虚拟机系统资源 链接&#xff1a;系统资源链接 提取码&#xff1a;0gat 说明&#xff1a;此处的系统资源是采用VMwareWorkstation 虚拟机进…

【postgreessql 】查询数据库表占用物理空间

查询单个表的磁盘使用量&#xff1a; SELECTrelname,pg_size_pretty ( pg_total_relation_size ( relid ) ) AS total_size FROMpg_catalog.pg_statio_user_tables; 查询所有表的总磁盘使用量&#xff1a; SELECTpg_size_pretty ( SUM ( pg_total_relation_size ( relid ) )…

【机器学习与实现】线性回归示例——波士顿房价分析

目录 一、创建Pandas对象并查看数据的基本情况二、使用皮尔逊相关系数分析特征之间的相关性三、可视化不同特征与因变量MEDV&#xff08;房价中值&#xff09;间的相关性四、划分训练集和测试集并进行回归分析 一、创建Pandas对象并查看数据的基本情况 boston.csv数据集下载&a…

《起风了》观后感

我想宫崎骏的电影是很多人心目中美好的回忆&#xff0c;每当听到有他的新电影要上映&#xff0c;总是迫不及待想去捧场&#xff0c;一刷二刷三刷却还是依然看得津津有味&#xff0c;这就是宫崎骏电影独特的魅力。《起风了》跟他的其他电影有很明显的不同&#xff0c;他的大部分…

Hive Partitioned Tables 分区表

Hive Partitioned Tables 分区表 1.分区表概念 Hive分区表&#xff08;Partitioned Tables&#xff09;是一种用于管理大量数据的机制&#xff0c;它可以将数据分散到不同的目录或分区中&#xff0c;以提高查询性能、优化数据存储和管理。 这种表结构可以根据某个列的值进行分…

【记录】Python3| 将 PDF 转换成 HTML/XML(✅⭐PyMuPDF+tqdm)

本文将会被汇总至 【记录】Python3&#xff5c;2024年 PDF 转 XML 或 HTML 的第三方库的使用方式、测评过程以及对比结果&#xff08;汇总&#xff09;&#xff0c;更多其他工具请访问该文章查看。 文章目录 PyMuPDF 使用体验与评估1 安装指南2 测试代码3 测试结果3.1 转 HTML …

【2024最新华为OD-C卷试题汇总】字符串分割(100分) - 三语言AC题解(Python/Java/Cpp)

&#x1f36d; 大家好这里是清隆学长 &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C卷的三语言AC题解 &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f497; 文章目录 前…

Springboot 集成 Consul 实现服务注册中心-05

因为后续很多模块都要用到注册中心&#xff0c;所以此处先实现此模块。 Consul简介 Consul是一个开源的服务发现和配置管理工具&#xff0c;具有跨平台、运行高效等特点。它由HashiCorp公司开发&#xff0c;并使用Go语言编写。Consul主要用于实现分布式系统中的服务发现、健康…

计算机毕业设计Python+Vue.js天气预测系统 中国气象质量采集与可视化 天气数据分析 天气可视化 天气大数据 天气爬虫 大数据毕业设计

摘要 随着科技技术的不断发展&#xff0c;人民物质生活质量不断提高&#xff0c;我们越来越关注身边的气象、空气等地理环境。对于普通居民我们会选择合适的气象进行出游&#xff0c;提高精神层面的生活质量&#xff1b;对于企业会关注气象变换状况&#xff0c;来定制相关的生产…