简单了解泛型

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

在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.mzph.cn/bicheng/7971.shtml

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

相关文章

如何O(1)判断一个数是不是x的幂

如何 O(1) 判断一个数是不是 x 的幂 (x 有限大) 数据在 32 位整数范围内 2 的幂 231. 2 的幂 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数 n&#xff0c;请你判断该整数是否是 2 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。…

sql注入练习

1.什么是SQL注入 SQL注入是比较常见的网络攻击方式之一&#xff0c;它不是利用操作系统的BUG来实现攻击&#xff0c;而是针对程序员编写时的疏忽&#xff0c;通过SQL语句&#xff0c;实现无账号登录&#xff0c;甚至篡改数据库 2.sql注入原理 攻击者注入一段包含注释符的SQL语…

能将图片转为WebP格式的WebP Server Go

本文完成于 2023 年 11 月 之前老苏介绍过 webp2jpg-online&#xff0c;可以将 webp 格式的图片&#xff0c;转为 jpg 等&#xff0c;今天介绍的 WebP Server Go 是将 jpg 等转为 webp 格式 文章传送门&#xff1a;多功能图片转换器webp2jpg-online 什么是 WebP ? WebP 它是由…

Vue 路由

单应用程序 SPA - Single Page Application 所有功能在一个html页面上实现 单页面应用 多用于 系统类网站/内部网站/文档类网站/移动端站点 多页面应用 多用于 公司官网/电商类网站 路由 单页面应用按需更新页面&#xff0c;需要明确访问路径和组件的对应关系 Vue中的路…

重学java 30.API 1.String字符串

于是&#xff0c;虚度的光阴换来了模糊 —— 24.5.8 一、String基础知识以及创建 1.String介绍 1.概述 String类代表字符串 2.特点 a.Java程序中的所有字符串字面值(如“abc”)都作为此类的实例(对象)实现 凡是带双引号的&#xff0c;都是String的对象 String s "abc&q…

python面试之mysql引擎选择问题

MySQL数据库提供了多种存储引擎&#xff0c;每种存储引擎有其特定的优势和场景适用。以下是几种常见的MySQL存储引擎及其特点&#xff1a; InnoDB&#xff1a; 支持事务&#xff0c;有回滚和提交事务的功能。 支持行级锁定&#xff0c;提供更高的并发。 支持外键约束&#…

修改ElTable组件的样式(element-plus)

效果展示 <div class"table_main"><ElTable:data"tableList":header-cell-style"{color: #ffffff,background: #6f7f93,}"class"table_border":highlight-current-row"false"><ElTableColumn type"inde…

Java笔记(其五)--流程控制

switch switch(a) { case ***: break; ***** default: break; } 需要注意的点&#xff1a; 其中的 a 的类型&#xff0c;只支持byte、short、int、char&#xff0c;不支持double、float、long&#xff08;string也是支持的&#xff0c;这里说的是基础的数据类型&#x…

CentOS 自建gitlab仓库:安装相关工具

所需环境 Node 安装项目依赖、项目打包运行Nginx 前端项目部署&#xff08;正向代理、反向代理、负载均衡等&#xff09;Git 自动化部署时 拉取代码使用GitLab 代码仓库GitLab-Runner GitLab的CI/CD执行器 一、安装Node 检测是否已安装 常用node -v 命令检测。 如果已安装&a…

百面算法工程师目录 | 深度学习目标检测、语义分割、分类上百种面试问答技巧

本文给大家带来的百面算法工程师是深度学习面试目录大纲&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;可以点击题目直达问题答案处&#xff0c;方便查找问题寻找答案。节约大家的时间。通过对这…

Docker 快速安装指南 (CentOS 7)

Docker 快速安装指南 (CentOS 7) 1. 更新现有的软件包 sudo yum update -y2. 安装必要的依赖包 sudo yum install -y yum-utils device-mapper-persistent-data lvm2yum-utils: 提供 yum-config-manager 工具&#xff0c;方便添加软件仓库。device-mapper-persistent-data 和…

7-115 差分矩阵

知识点:差分 输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,c,其中 (x1,y1) 和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将选中的子矩阵中的每个元素的值加上 c。 请你将进行完所有操作后的矩阵输出。 1≤n,…

ACGO欢乐赛#19题解

ACGO欢乐赛#19题解 T1、人工AI T2、判闰年 T3、一天中的某个时刻 T4、二进制下1的个数 T5、修正字符 T6、恰排骨 T7、买零食 T8、真-签到题

为什么你的企业需要微信小程序?制作微信小程序有什么好处?

什么是小程序&#xff1f; WeChat小程序作为更大的WeChat生态系统中的子应用程序。它们就像更小、更基本的应用程序&#xff0c;在更大的应用程序&#xff08;WeChat&#xff09;中运行。这些程序为用户提供了额外的高级功能&#xff0c;以便在使用WeChat服务时加以利用。根据…

sqlserver数据库查询注释/表结构的语句

sqlserver数据库和mysql查看的方式不一样&#xff0c;sqlserver需要通过语句来查&#xff0c;我们只需要替换掉语句里的表名就可以。 1查看表名&#xff0c;字段名&#xff0c;字段注释 SELECT A.name AS table_name, B.name AS column_name, C.value AS column_description F…

Docker 快速搭建 Kafka 集群

Docker 快速搭建 Kafka 集群 你是否想要一个 Kafka 集群&#xff0c;但又不想经历繁琐的手动配置过程&#xff1f;别担心&#xff0c;有了 Docker 和 Docker Compose&#xff0c;我们可以轻松快捷地搭建一个 Kafka 集群&#xff0c;让你能专注于享受实时数据流处理的乐趣。 环…

Mongodb操作与Java(三)增删改语句及DDL新增或删除字段

MongoDB概念 MongoDB 基本概念指的是学习 MongoDB 最先应该了解的词汇&#xff0c;比如 MongoDB 中的"数据库"、"集合"、"文档"这三个名词&#xff1a; 文档&#xff08;Document&#xff09;&#xff1a; 文档是 MongoDB 中最基本的数据单元&…

DeepSeek发布全新开源大模型,GPT-4级别能力 价格仅百分之一

最新国产开源MoE大模型&#xff0c;刚刚亮相就火了。 DeepSeek-V2性能达GPT-4级别&#xff0c;但开源、可免费商用、API价格仅为GPT-4-Turbo的百分之一。 因此一经发布&#xff0c;立马引发不小讨论。 从公布的性能指标来看&#xff0c;DeepSeek-V2的中文综合能力超越一众开源…

运维实施工程师之Linux服务器全套教程

一、Linux目录结构 1.1 基本介绍 Linux 的文件系统是采用级层式的树状目录结构&#xff0c;在此结构中的最上层是根目录“/”&#xff0c;然后在此目录下再创建其他的目录。 在 Linux 世界里&#xff0c;一切皆文件&#xff08;即使是一个硬件设备&#xff0c;也是使用文本来标…

校园论坛系统基于PHP的校园管理系统毕设校园好感度系统 校园文化建设系统APP小程序H5前后端源码交付支持二开,一次付款,终生使用

APP小程序H5前后端源码交付&#xff0c;支持二开&#xff0c;一次付款&#xff0c;终身使用&#xff0c;免费更新系统本身源码。 校园社交网络系统开发是一个复杂且综合性的项目&#xff0c;旨在为学生、教师和管理人员提供一个互动、分享和交流的平台。以下是一个关于校园社交…