当前位置: 首页 > news >正文

数据结构——包装类泛型

一:包装类

在Java中,由于基本类型不是继承⾃Object,为了在泛型代码中可以⽀持基本类型,Java给每个基本类型都对应了⼀个包装类型。
类型、基础数据类型(内置数据类型):byte int short long float double boolean char 、
引用类型:所有的类(引用类型)都是直接间接继承Object类。
java是希望把所有的类型统一达成Object体系
包装类:标准库中创建了一组类,把内置类型的变量,包一下。

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

除了 Integer 和 Character, 其余基本类型的包装类都是⾸字⺟⼤写。

1.2:装箱和拆箱

虽然包装类,确实是类,在使用的时候,进行算术运算,还是需要转成内置类型,在进行运算。
包装类和内置类型转换。
内置类型-》包装类:装箱
包装类-》内置类型:拆箱

int i = 10;// 装箱操作,新建⼀个 Integer 类型对象,将 i 的值放⼊对象的某个属性中Integer ii = Integer.valueOf(i);Integer ij = new Integer(i);// 拆箱操作,将 Integer 对象中的值取出,放到⼀个基本数据类型中int j = ii.intValue();

这个我们了解一下就可以了,现在的从ava8开始,已经可以自动拆箱装箱了。

1.3:自动拆箱和装箱

public class Test {  public static void main(String[] args) {  //内置类型,赋值给包装类  // Integer i = 10;  //包装类,赋值给内置类型、自动拆箱  // int n=i;  Integer i = 10;  Integer j = 20;  System.out.println(i+j);//这里的+就是针对两个Integer先转int在计算

对于包装类来说,拿过来直接用进行了,当内置类型来用。
但有的地方需要使用包装类,不能使用内置类型。

面试题:
下列代码输出什么,为什么?
Integer a = 127;  
Integer b = 127;  
Integer c = 128;  
Integer d = 128;  
System.out.println(a == b);  
System.out.println(c == d);
//true
//false

jvm针对Integrt这样的常量也做了优化
-128->127这个范围的数字,Integrt对象提前创建好了,保存到了一个“常量池”中。
jvm缓存了哪些integer对象,取决于jvm的实现。

二:范型

2.1:什么是泛型

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

2.2:引出泛型

泛型就是把所有程序员所需要的类型都包含上。

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

class MyArray {public Object[] array = new Object[10];public Object getPos(int pos) {return this.array[pos];}public void setVal(int pos,Object val) {this.array[pos] = val;}}public class TestDemo {public static void main(String[] args) {MyArray myArray = new MyArray();myArray.setVal(0,10);myArray.setVal(1,"hello");//字符串也可以存放String ret = myArray.getPos(1);//编译报错System.out.println(ret);}}

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

三:语法

基础语法

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

其他写法:

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

四:泛型的使用

package object.package1;  
class MyArrayTemplate<T> {  //此时arr是T[]类型 T是啥类型? 还不知道,得在后面实例化的时候才知道  //由于T类型位置,不能直接new T[]  private T[] arr=(T[]) new Object[10];  public T get (int index){  return arr[index];  }  public void set (int index, T value){  arr[index]=value;  }  }  public class Test3 {  public static void main(String[] args) {  //针对MyArrayTemplate的进行实例化  //泛型参数类型T是Integer  //针对arr来说,就只能存储Integer类型  MyArrayTemplate<Integer> myArray = new MyArrayTemplate<Integer>();  myArray.set(0, 10);  System.out.println(myArray.get(0));  //针对MyArrayTemplate的进行实例化  //泛型参数类型T是String  MyArrayTemplate<String> myArray2 = new MyArrayTemplate<String>();  myArray2.set(0, "hello");  System.out.println(myArray2.get(0));  }  
}
//10
//hello

针对泛型参数来说,只能指定引用类型,不能指定内置类型(int 就不可以。)
泛型这一套语法体系,底层还是靠Object这一些列的继承来完成的。
了解: 【规范】类型形参⼀般使⽤⼀个⼤写字⺟表⽰,常⽤的名称有:
E 表⽰ Element
K 表⽰ Key
V 表⽰ Value
N 表⽰ Number
T 表⽰ Type
S, U, V 等等 - 第⼆、第三、第四个类型

也可以省略实例化的一部分:(类型推导)
MyArrayTemplate<Integer> myArray = new MyArrayTemplate<Integer>();  
转换为:
MyArrayTemplate<Integer> myArray = new MyArrayTemplate<>();  

五:裸类型

5.1: 说明

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

MyArray list = new MyArray();
只是警告但不报错,
注意: 我们不要⾃⼰去使⽤裸类型,裸类型是为了兼容⽼版本的 API 保留的机制
下⾯的类型擦除部分,我们也会讲到编译器是如何使⽤裸类型的。
⼩结:
1. 泛型是将数据类型参数化,进⾏传递
2. 使⽤ <T> 表⽰当前类是⼀个泛型类。
3. 泛型⽬前为⽌的优点:数据类型参数化,编译时⾃动进⾏类型检查和转换

六:泛型如何编译的

6.1 :擦除机制

那么,泛型到底是怎么编译的?
1. 基本概念:
在编译时,Java 编译器会将泛型类型信息从代码中移除,这个过程就叫做类型擦除。
擦除后,泛型类型会被替换为其边界类型(通常是 Object)或者指定的类型。
2. 擦除过程:
将泛型参数替换为其边界或 Object。
在必要的地⽅插⼊类型转换以保持类型安全。
⽣成桥接⽅法以保持多态性。

七 :泛型的上界

针对某个类泛型参数,能填啥,做出限制。
上界:约定了泛型参数的父类,然后有一个界限。
例如:泛型参数只能填数字不能填字符串
或者泛型参数只能填Animal,就是有限制。

7.1:语法

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

7.2:实例

public class Test4 <T extends Number> {  }
继承Number父类,它的子类只能是数字
Test4<Integer> l1; // 正常,因为 Integer 是 Number 的⼦类型Test4<String> l2;//// 编译错误,因为 String 不是 Number 的⼦类型
这样就不可以使用,
eg:
public class Test4 <T extends Number> {  public static void main(String[] args) {  Test4<Integer> t1 = new Test4<Integer>();  Test4<Double> t2 = new Test4<Double>();  Test4<Float> t3 = new Test4<Float>();  Test4<Long> t4 = new Test4<Long>();  Test4<Short> t5 = new Test4<Short>();  Test4<Byte> t6 = new Test4<Byte>();  Test4<String> t7 = new Test4<String>();//String表示Number子类

也就是继承,然后类型匹配,不能匹配就不执行。

八:通配符(统统匹配)

public class Test5 <T>{  public static void main(String[] args) {  Test5<Integer> t1 = new Test5<Integer>();  //报红就不能实例化,因为泛型参数不匹配  t1= new Test5<String>();  //这个情况就是不挑食,无论泛型参数是什么,都可以通过t来实例化  //此处?就是通配符  Test5<?> t= new Test5<Integer>();  t= new Test5<String>(); 

在"?"的基础上⼜产⽣了两个⼦通配符:

? extends 类:设置通配符上限:

//指定了通配符的上界  
//此时t1可以实例化Integer,String,Double等所有Number的子类  
Test5<? extends Number> t1= new Test5<Integer>();  //错误写法,String类型不是Number的子类,所以编译报错  
t1 = new Test5<String>();

? super 类:设置通配符下限(都是一样的规则,也就是不能超过子类)

九:总结

本片博客讲述了包装类和泛型,为接下来进入数据结构,开启新篇章。

大家也要了解以下几个问题:
包装类:
1包装类是什么
2包装类和内置类型的对应关系
3包装类和内置类型的转换(装箱拆箱)

泛型:
1:泛型解决了什么
2:泛型类咋怎么定义
3:泛型类怎么实例化

http://www.dtcms.com/a/418526.html

相关文章:

  • 中国建设银行贵州分行网站安卓app制作入门教程
  • 17. 整个网站建设中的关键是专业客户管理系统
  • RuoYi 学习笔记 2:常用功能
  • 负载均衡式的在线OJ项目编写(五)
  • USBKey智能密码钥匙:从硬件安全到未来信任架构的深度技术解析
  • K8s日志架构:Sidecar容器实践指南
  • 前端开发,iframe 相关经验总结
  • 前端-JS基础-day3
  • MIT 6.S081 文件系统的崩溃恢复
  • 图片展示模块网站做一个多少钱影视vip网站建设教程
  • 环境搭建,Ubuntu 安装、客户端使用与性能认知
  • 合肥市城乡和建设网站南充建设企业网站
  • Music Muse AI音乐生成器全面解析:免费创作高质量音乐的核心要素
  • Go 语言中的结构体
  • Nest 文件上传与下载
  • 2025-9-28学习笔记
  • 深度学习(十三):向量化与矩阵化
  • 矩阵结构体 图片绘制 超级玛丽demo6
  • 承接网站开发 app开发学校网站建设责任书
  • 网站 管理检察内网门户网站建设
  • LeetCode 390 消除游戏
  • 汕头seo建站新品发布会的作用
  • 基于深度学习的CT扫描图像肝脏肿瘤智能检测与分析系统【python源码+Pyqt5界面+数据集+训练代码】
  • Edge 浏览器安装selenium
  • 学习:SSMP整合综合案例(2025
  • 如何有效抵御DDoS攻击:全面应对策略解析
  • mobaxterm软件下载_mobaxterm安装包下载_mobaxterm安装教程下载_mobaxterm网盘下载
  • Spring依赖注入问题清单及解决方案
  • KingbaseES数据库SSL安全传输与数据完整性保护技术详解
  • 微网站如何做如何对网站用户分析