包装类, 泛型---java

目录

一. 包装类

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

1.2 装箱和拆箱

 二. 泛型

2.1什么是泛型

2.2泛型的引入

 2.3 泛型类语法 

 2.4 泛型类的使用

 2.5 裸类型(Raw Type)(了解)

 2.6 泛型是如何编译的 

2.7 泛型的上界

2.8 泛型方法 


一. 包装类

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

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

包装类在之前我们就使用过, 使我们写代码更加的方便 

1.2 装箱和拆箱

装箱(装包): 把一个基本数据类型转变为包装类型

拆箱(拆包): 把一个包装类型转变为基本数据类型

int i = 10 ;
Integer ii = i ; // 自动装箱
Integer ii = Integer . valueOf ( i ); //显示装箱 ---类名.valueOf 说明该方法时用static修饰的
Integer jj = new Integer(10) ;
int j = jj ; // 自动拆箱
int j = jj . intValue (); //显示拆箱

注:拆箱时, 我们可以将数据拆成我们想要的类型 

Integer jj = new Integer(10);

double d = jj.doubleValue();//拆成double类型

System.out.println(d);

//输出结果

10.0

 下面看一道面试题:

思考 : 为什么上述代码只是将100改成200, 输出的结果却不同呢?   

上述我们唯一做的动作就是装箱, 那么装箱时, 调用的方法是Integer.valueOf(), 按住Ctrl点进去查看valueOf的源码, 我们发现:

 我们传入的参数, 如果在一个low和high之间, 那么就返回一个数组某下标的值, 如果不在这个范围内, 那么就new一个对象, 此时即使传入一样的参数, 返回的值肯定是不同的.  那么我们猜测, 200就不在low和high之间, 而100在low和high之间. 

那么我们点进去low和high的源码, 发现low = -128 , high = 127, 我们的猜测是正确的, 那么cache数组是怎么回事呢?

我们计算一下这个数组:

 二. 泛型

2.1什么是泛型

一般的类和方法,只能使用具体的类型 : 要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。
----- 来源《 Java 编程思想》对泛型的介绍。
泛型是在 JDK1.5 引入的新的语法,通俗讲,泛型: 就是适用于许多许多类型 。从代码上讲,就是对类型实现了参数化。

2.2泛型的引入

实现一个类,类中包含一个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员方法返回数组中某个下标的值.
思路:
1. 我们以前学过的数组,只能存放指定类型的元素,例如: int[] array = new int[10]; String[] strs = new String[10];
2. 所有类的父类,默认为 Object 类。数组是否可以创建为 Object?

代码示例:

问题:
以上代码实现后 发现
1. 任何类型数据都可以存放
2. 1 号下标本身就是字符串,但是确编译报错。getPos返回值是Object, 用String接收, 必须进行强制类型转换
虽然在这种情况下,当前数组任何数据都可以存放,但是,更多情况下,我们还是希望他只能够持有一种数据类型。而不是同时持有这么多类型。所以,泛型的主要目的:就是指定当前的容器,要持有什么类型的对象。让编译 器去做检查。 此时,就需要把类型,作为参数传递。需要什么类型,就传入什么类型。
那么我们对上述代码进行改写:

 ① MyArray<T>  -----  类名后的 <T> 代表占位符,表示当前类是一个泛型类

了解: 【规范】类型形参一般使用一个大写字母表示,常用的名称有:
E 表示 Element
K 表示 Key
V 表示 Value
N 表示 Number
T 表示 Type
S, U, V 等等 - 第二、第三、第四个类型

②T[] array = (T[])new Object[10] ----  创建泛型类数组

T[] array = (T[])new Object[10], 并不是一个最好的写法, 最好的写法是:

Object[] array = new Object[10];

不能new泛型类型的数组 
T [] ts = new T [ 5 ]; // 是不对的

③ MyArray<Integer> myArray = new MyArray<>()  -----   创建泛型类对象, 类型后加入 <Integer> 指定当前类型 后面的<>中的内容可以省略

④  myArray.setVal(2,"bit")  -----   代码编译报错,此时因为在③处指定类当前的类型,此时编译器会在存放元素的时候帮助我们进行类型检查。

泛型, 是编译时期的机制, 在运行时, 没有泛型的概念

注:<>中的内容不能是基本数据类型, 只能是引用类型/包装类

想要存放String类型的数据:

 2.3 泛型类语法 

class 泛型类名称 < 类型形参列表 > {
        // 这里可以使用类型参数
}
class ClassName < T1 , T2 , ..., Tn > {
}
class 泛型类名称 < 类型形参列表 > extends 继承类 /* 这里可以使用类型参数 */ {
        // 这里可以使用类型参数
}
class ClassName < T1 , T2 , ..., Tn > extends ParentClass < T1 > {
        // 可以只使用部分类型参数
}

 2.4 泛型类的使用

泛型类 < 类型实参 > 变量名 ; // 定义一个泛型类引用
new 泛型类 < 类型实参 > ( 构造方法实参 ); // 实例化一个泛型类对象
MyArray < Integer > list = new MyArray < Integer > ();
//当编译器可以根据上下文推导出类型实参时,可以省略类型实参的填写
MyArray < Integer > list = new MyArray <> (); // 可以推导出实例化需要的类型实参为 Integer
注意:泛型只能接受类,所有的基本数据类型必须使用包装类!

 2.5 裸类型(Raw Type)(了解)

裸类型是一个泛型类但没有带着类型实参,例如 MyArrayList 就是一个裸类型

MyArray list = new MyArray();  

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

 2.6 泛型是如何编译的 

那么,泛型到底是怎么编译的?这个问题,也是曾经的一个面试问题。泛型本质是一个非常难的语法,要理解好他还是需要一定的时间打磨。
通过命令: javap -c 查看字节码文件,所有的 T 都是 Object 。
在编译的过程当中,将所有的 T替换为Object 这种机制,我们称为: 擦除机制 。
Java 的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息。

2.7 泛型的上界

 在定义泛型类时,有时需要对传入的类型变量做一定的约束,可以通过类型边界来约束。

语法:

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

例:

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

表示: 只接受 Number 或 Number的子类型 作为 E 的类型实参 

MyArray < Integer > l1 ; // 正常,因为 Integer 是 Number 的子类型
MyArray < String > l2 ; // 编译错误,因为 String 不是 Number 的子类型

了解:

1.  没有指定类型边界 E,可以视为 E extends Object  

2. 泛型没有下界

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

 显然这样是错误的, 因为擦除机制将T替换成Object类, 而引用类型是不能直接比较大小的, 需要使用compareTo方法, 并实现Comparable接口,  我们点进去Object的源码看发现: 

Object类并没有实现Comparable接口 

正确的写法应该是:

意味着, 传入的参数必须是继承了Comparable接口的类, 那么Integer我们点进去查看:

 Integer是继承了Comparable接口的. 

如果我们重新定义一个类当参数:

是不被允许的, 因为没有Person没有实现Comparable接口

正确写法:

2.8 泛型方法 

语法:

方法限定符 < 类型形参列表 > 返回值类型 方法名称 ( 形参列表 ) { ... }

上述代码可以写成 泛型方法:

 

当这个泛型方法是静态的时,  我们就不用实例化对象, 直接通过类来调用泛型方法 

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

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

相关文章

uniapp实战 —— 竖排多级分类展示

效果预览 完整范例代码 页面 src\pages\category\category.vue <script setup lang"ts"> import { getCategoryTopAPI } from /apis/category import type { CategoryTopItem } from /types/category import { onLoad } from dcloudio/uni-app import { compu…

vue指令

v-text 更新元素的 textContent。如果要更新部分的 textContent&#xff0c;需要使用 {{ Mustache }} 插值。 <span v-text"msg"></span> <!-- 和下面的一样 --> <span>{{msg}}</span>v-html 更新元素的 innerHTML。注意&#xff1a;内…

基于高通MSM8953平台android9.0的GPIO驱动开发

2.1、注册设备&#xff1a; 2.1.1、添加编译选项&#xff1a; 1&#xff09;、修改kernel/msm-4.9/drivers/leds下Makefile文件&#xff1a; obj-$(CONFIG_LED_GPIO) led_gpio.o 2&#xff09;、修改kernel/msm-4.9/drivers/leds下Kconfig文件&#xff1a; config LED_GPIO…

Java实现归并排序算法

归并排序算法 &#xff08;1&#xff09;基本思想&#xff1a;归并&#xff08;Merge&#xff09;排序法是将两个&#xff08;或两个以上&#xff09;有序表合并成一个新的有序表&#xff0c;即把待排序序列分为若干个子序列&#xff0c;每个子序列是有序的。然后再把有序子序…

蛋白质序列FeatureDict转化为TensorDict

主要转化语句为 tensor_dict {k: tf.constant(v) for k, v in np_example.items() if k in features_metadata}。 增加了特征名称的选择&#xff0c;不同特征维度&#xff0c;特征数的判断等。 from typing import Dict, Tuple, Sequence, Union, Mapping, Optional #import …

postgresql_conf中常用配置项

在 PostgreSQL 的 postgresql.conf 配置文件中&#xff0c;有许多常用的配置项&#xff0c;这些配置项可以根据特定需求和性能优化进行调整。以下是一些常用的配置项及其作用&#xff1a; 1. shared_buffers 用于设置 PostgreSQL 实例使用的共享内存缓冲区大小。增加此值可以…

游戏被攻击该怎么办?游戏盾该如何使用,游戏盾如何防护攻击

随着Internet互联网络带宽的增加和多种DDOS黑客工具的不断发布&#xff0c;DDOS拒绝服务攻击的实施越来越容易&#xff0c;DDOS攻击事件正在成上升趋势。出于商业竞争、打击报复和网络敲诈等多种因素&#xff0c;导致很多商业站点、游戏服务器、聊天网络等网络服务商长期以来一…

Nacos 配置加密功能也太鸡肋了吧,有种更好的方式

大家好&#xff0c;我是风筝&#xff0c;微信搜「古时的风筝」&#xff0c;更多干货 当项目中用了 Nacos 做配置中心&#xff0c;是不是所有的配置都放到里面呢&#xff0c;大部分时候为了省事和统一&#xff0c;系统所有的配置都直接放在里面了&#xff0c;有时候&#xff0c…

什么是自动化测试框架?常用的自动化测试框架有哪些?

无论是在自动化测试实践&#xff0c;还是日常交流中&#xff0c;经常听到一个词&#xff1a;框架。之前学习自动化测试的过程中&#xff0c;一直对“框架”这个词知其然不知其所以然。 最近看了很多自动化相关的资料&#xff0c;加上自己的一些实践&#xff0c;算是对“框架”…

Redis相关知识

yum安装redis 使用以下命令&#xff1a;直接将redis安装到Linux服务器&#xff08;Xshell&#xff09;中 yum -y install redis 启动redis 使用以下命令&#xff0c;以后台运行方式启动redis redis-server /etc/redis.conf & 操作redis 使用以下命令启动redis客户端 redis-…

RFID在新能源工厂大放异彩

RFID在新能源工厂大放异彩 我国在十四五规划中提出了建设绿色低碳发展的目标&#xff0c;新能源产业成为了国家发展的重点领域之一&#xff0c;开始大力支持各种新能源厂商发展。各个厂商之间不仅比产品、比技术。也比生产想要降本增效&#xff0c;为了实现这一目标&#xff0…

MBD Introduction

介绍 MATLAB是MathWorks公司的商业数学软件&#xff0c;应用于科学计算、可视化以及交互式程序设计等高科技计算环境。Simulink是MATLAB中的一种可视化仿真工具。 Simulink是一个模块图环境&#xff0c;用于多域仿真以及基于模型的设计。它支持系统设计、仿真、自动代码生成以…

Spring基于xml半注解开发

目录 Component的使用 依赖注解的使用 非自定义Bean的注解开发 Component的使用 基本Bean注解&#xff0c;主要是使用注解的方式替代原有的xml的<bean>标签及其标签属性的配置&#xff0c;使用Component注解替代<bean>标签中的id以及class属性&#xff0c;而对…

算法Day26 数位统计

数位统计 Description 给你一个整数n&#xff0c;统计并返回各位数字都不同的数字x的个数&#xff0c;其中0 ≤ x < 10^n。 Input 输入整数n 0≤n≤13 Output 输出整数个数 Sample 代码 import java.util.Scanner;public class Main {public static void main(String[] ar…

一个Oracle Application Container的实例

本例基本涵盖了Oracle Multitenant功能中application container的以下内容&#xff1a; 创建application container/root创建application PDB创建application SEED在application root中安装application在application root中升级application同步application 整个过程如下 创建…

Epoll服务器(ET工作模式)

目录 Epoll ET服务器设计思路Connection类TcpServer类 回调函数Accepter函数Recever函数Sender函数Excepter函数 事件处理套接字相关接口封装运行Epoll服务器 Epoll ET服务器 设计思路 在epoll ET服务器中&#xff0c;我们需要处理如下几种事件&#xff1a; 读事件&#xff…

基于javeweb实现的图书借阅管理系统

一、系统架构 前端&#xff1a;jsp | js | css | jquery 后端&#xff1a;servlet | jdbc 环境&#xff1a;jdk1.7 | mysql | tocmat 二、代码及数据库 三、功能介绍 01. 登录页 02. 首页 03. 图书管理 04. 读者管理 05. 图书分类管理 06. 图书借阅信息 07. 图书归还信…

CDN加速技术:降低服务器与网站成本的智慧选择

随着互联网的飞速发展&#xff0c;网站的访问量不断攀升&#xff0c;服务器负载压力逐渐增大。为了提高用户体验、降低服务器成本&#xff0c;并确保网站的高可用性&#xff0c;CDN&#xff08;内容分发网络&#xff09;加速技术应运而生。本文将从服务器与网站成本的角度分析C…

NLP项目实战01--电影评论分类

介绍&#xff1a; 欢迎来到本篇文章&#xff01;在这里&#xff0c;我们将探讨一个常见而重要的自然语言处理任务——文本分类。具体而言&#xff0c;我们将关注情感分析任务&#xff0c;即通过分析电影评论的情感来判断评论是正面的、负面的。 展示&#xff1a; 训练展示如下…

比较不同聚类方法的评估指标

归一化互信息&#xff08;NMI&#xff09; 要求&#xff1a;需要每个序列的真实标签&#xff08;分类信息&#xff09;