Java——包装类及认识泛型

embedded/2024/9/23 15:49:42/

包装类:

        在学习泛型之前我们一定要认识包装类。

        在Java 中,由于基本类型不是继承自 Object ,为了在泛型代码中可以支持基本类型, Java 给每个基本类型都对应了一个包装类型。
除了int类型和char类型的包装类不是它们对应的基本类型的大写之外,其他的都是将基本类型的首字母大写!

包装类中也有对应的许多方法,例如:将字符串类型转为整型: 

我们以Integer包装类为例研究。

拆箱和装箱:

        拆箱和装箱也被称为拆包和装包:

装箱:

也就是将基本类型变成包装类的过程:

例如:

此时就对基本类型完成了装箱过程:

需要调用Integer的静态方法完成装箱:

这个静态方法是什么意思呢?

可以一起看看,源码如下:

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

首先进入源码有一个if语句,我们看看能能不能看懂。

Integer.low和Integer.high是什么意思呢?

我们同样找到low和high中,发现low是-128,high是127,也就是当我们传过来的参数如果小于-128或者大于127,这时候先调用Integer的构造函数之后就直接new一个新的Integer对象返回。

将类中的value初始化,完成整个装箱过程!!

但是如果此时我输入的值在-128和127之间会发生什么?
继续来看:

此时返回一个数组对应的值,cache是该类一开始就定义的一个Integer数组类型的成员变量:

那么这个数组中放的是什么呢?

在一开始的静态代码块中有初始化:

发现这个数组中首先只有(127+128+1 = 256)的大小,j = -128;之后将参数为-128 - 127的Integer类型的放在数组中,下标从0 - 255!!

这时候就明白了,原来这个数组中存放的就是-128到127的Integer类型的变量。

所以当我们传参如果大于127或者小于-128的时候,这时候会计算一个位置然后返回,如果是3,那么就返回3+128 = 131位置的对应的Integer对象,131位置上Integer初始化的value正好是3。

如上就是原理图!!

拆箱:

        就是将包装类变成基本类型:

例如:

java">    public static void main(String[] args) {Integer i = Integer.valueOf(10);int a = i.intValue();System.out.println(a);}

这就是拆箱过程,也就是调用封装对象的intValue方法。

源码如下;:

这个通俗易懂直接返回一个int类型的值。 

自动拆箱和装箱:

        名表了拆箱和装箱的原理,也知道拆线和装箱需要调用哪个方法。

        但是此时我写这样的代码,看看编译器能否通过编译!

首先没有报错,再其次打印结果如下:

此时有两个问题:

        1.Integer引用类型为什么可以直接接受一个int类型的变量?

        2.为什么我直接打印Integer引用类型变量,打印结果是一个10?

接下来一一解答该问题:

        1.编译器会为我们自动完成拆箱和装箱的过程!

        2.Integer包装类中已经重写了toString方法!! 

自动拆箱演示过程:
 

泛型:

什么是泛型:

        泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数0化。

语法:

class 泛型类名称 < 类型形参列表 > {
// 这里可以使用类型参数
}
class ClassName < T1 , T2 , ..., Tn > {

}

class 泛型类名称 < 类型形参列表 > extends 继承类 /* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName < T1 , T2 , ..., Tn > extends ParentClass < T1 > {
// 可以只使用部分类型参数
}
java">class MyArray<T> {
public T[] array = (T[])new Object[10];//1
public T getPos(int pos) {
return this.array[pos];
}
public void setVal(int pos,T val) {
this.array[pos] = val;
}
}
public class TestDemo {
public static void main(String[] args) {
MyArray<Integer> myArray = new MyArray<>();//2
myArray.setVal(0,10);
myArray.setVal(1,12);
int ret = myArray.getPos(1);//3
System.out.println(ret);
myArray.setVal(2,"bit");//4
}
}
代码解释:
1. 类名后的 <T> 代表占位符,表示当前类是一个泛型类
了解: 【规范】类型形参一般使用一个大写字母表示,常用的名称有:
E 表示 Element
K 表示 Key
V 表示 Value
N 表示 Number
T 表示 Type
S, U, V 等等 - 第二、第三、第四个类型
2. 注释 1 处,不能 new 泛型类型的数组:
class 泛型类名称 < 类型形参列表 > extends 继承类 /* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName < T1 , T2 , ..., Tn > extends ParentClass < T1 > {
// 可以只使用部分类型参数
}
class MyArray < T > {
public T [] array = ( T []) new Object [ 10 ]; //1
public T getPos ( int pos ) {
return this . array [ pos ];
}
public void setVal ( int pos , T val ) {
this . array [ pos ] = val ;
}
}
public class TestDemo {
public static void main ( String [] args ) {
MyArray < Integer > myArray = new MyArray <> (); //2 当编译器可以根据上下文推导出类型实参 时,可以省略类型实参的填写
myArray . setVal ( 0 , 10 );
myArray . setVal ( 1 , 12 );
int ret = myArray . getPos ( 1 ); //3
System . out . println ( ret );
myArray . setVal ( 2 , "bit" ); //4
}
}
T [] ts = new T [ 5 ]; // 是不对的
3. 注释 2 处,类型后加入 <Integer> 指定当前类型
4. 注释 3 处,不需要进行强制类型转换
5. 注释 4 处,代码编译报错,此时因为在注释 2 处指定类当前的类型,此时在注释 4 处,编译器会在存放元素的时候帮助我们进行类型检查。

http://www.ppmy.cn/embedded/115668.html

相关文章

UniApp如何打包成客户端应用程序

像flutter是支持PC宽屏、桌面平台&#xff08;Windows/macOS/Linux&#xff09;&#xff0c;我一直在期望UniApp什么时候也支持PC&#xff0c;桌面平台&#xff0c;终于盼到了。 1、支持PC宽屏 从uni-app 2.9起&#xff0c;支持PC宽屏的适配。 uni-app提供的屏幕适配方案&am…

Leetcode 2464. 有效分割中的最少子数组数目

1.题目基本信息 1.1.题目描述 给定一个整数数组 nums。 如果要将整数数组 nums 拆分为 子数组 后是 有效的&#xff0c;则必须满足: 每个子数组的第一个和最后一个元素的最大公约数 大于 1&#xff0c;且 nums 的每个元素只属于一个子数组。 返回 nums 的 有效 子数组拆分中…

Matlab|电-气-热综合能源系统耦合优化调度

1 主要内容 程序主要做的是一个考虑电、热、气网耦合调度的综合能源系统优化调度模型&#xff0c;考虑了电网与气网&#xff0c;电网与热网的耦合&#xff0c;电网部分为10机39节点的综合能源系统&#xff0c;热网为6节点&#xff0c;气网部分为比利时20节点气网&#xff0c;潮…

python机器人编程——用手机web远程视频监控并控制小车驾驶(上篇vrep仿真)

目录 一、前言二、技术架构三、设备端实现四、服务控制端实现&#xff08;1&#xff09;摄像头服务模块&#xff08;2&#xff09;web服务器 五、web端实现&#xff08;1&#xff09;视频显示&#xff08;2&#xff09;驾驶盘的实现&#xff08;3&#xff09;心跳 六、总结七、…

MongoDB 关系

MongoDB 关系 MongoDB 是一种流行的 NoSQL 数据库,它使用文档存储数据。与传统的关系型数据库不同,MongoDB 不使用表格和行来存储数据,而是使用集合和文档。在 MongoDB 中,一个文档是一个 BSON(二进制 JSON)对象,它类似于 JSON 对象,但包含更多的数据类型。 MongoDB …

了解华为云容器引擎(Cloud Container Engine)

1.什么是云容器引擎&#xff1f; 云容器引擎&#xff08;Cloud Container Engine&#xff0c;简称CCE&#xff09;提供高度可扩展的、高性能的企业级Kubernetes集群。借助云容器引擎&#xff0c;您可以在华为云上轻松部署、管理和扩展容器化应用程序。云容器引擎是一个企业级的…

去耦合的一些建议

尽量少用全局变量&#xff0c;以减少状态共享和潜在的副作用。 模块化设计&#xff1a;将代码分成小模块&#xff0c;每个模块独立实现特定功能&#xff0c;减少模块之间的相互依赖。 封装&#xff1a;将数据和操作封装在类中&#xff0c;控制对内部状态的访问&#xff0c;避…

【系统架构设计师】特定领域软件架构(经典习题)

更多内容请见: 备考系统架构设计师-核心总结索引 文章目录 【第1~2题】【第3~4题】【第5~6题】【第7~8题】【第9~10题】【第11~12题】【第13~14题】【第15~17题】【试题一(共25分)】【问题 1】(13 分)【第1~2题】 特定领域软件架构(Domain Specific Software Architecture…