常用类一(包装类)

news2024/9/30 9:20:57

目录

基本数据类型的包装类

包装类基本知识

包装类的用途

自动装箱和拆箱

自动装箱:

自动拆箱:

包装类的缓存问题


基本数据类型的包装类

        八种基本数据类型并不是对象,为了将基本类型数据和对象之间实现互 相转化,JDK 为每一个基本数据类型ᨀ供了相应的包装类。

包装类基本知识

        Java 是面向对象的语言,但并不是“纯面向对象”的,因为我们经常用到的基本数据类 型就不是对象。但是我们在实际应用中经常需要将基本数据转化成对象,以便于操作。比 如:将基本数据类型存储到 Object[ ]数组或集合中的操作等等。

        为了解决这个不足,Java 在设计类时为每个基本数据类型设计了一个对应的类进行代 表,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。

        包装类均位于 java.lang 包,八种包装类和基本数据类型的对应关系如下

基本数据类型对应的包装类
基本数据类型包装类
byteByte
booleanBoolean
shortShort
charCharacter
intInteger
longLong
floatFloat
doubleDouble

        在这八个类名中,除了 Integer 和 Character 类以外,其它六个类的类名和基本数据类 型一致,只是类名的第一个字母大写而已。

        在这八个类中,除了 Character 和 Boolean 以外,其他的都是“数字型”,“数字型”都是 java.lang.Number 的子类。Number 类是抽象类,因此它的抽象方法,所有子类都需要ᨀ供 实现。Number 类提供了抽象方法:intValue()、longValue()、floatValue()、doubleValue(), 意味着所有的“数字型”包装类都可以互相转型。

Number的子类:

Number的抽象方法:

包装类:

public class WrapperClassTest {
    public static void main(String[ ] args) {
        Integer i = new Integer(10);
        Integer j = new Integer(50);
    }
}

包装类的用途

对于包装类来说,这些类的用途主要包含两种:

  1. 作为和基本数据类型对应的类型存在,方便涉及到对象的操作,如 Object[ ]、 集合等的操作。
  2. 包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法 (这些操作方法的作用是在基本数据类型、包装类对象、字符串之间提供相互 之间的转化!)。

包装类的使用

public class Test {
    public static void main(String[ ] args) {
        Test test = new Test();
        test.testInteger();
    }
    /** 测试 Integer 的用法,其他包装类与 Integer 类似 */
    void testInteger() {
        // 基本类型转化成 Integer 对象
        Integer int1 = new Integer(10);
        Integer int2 = Integer.valueOf(20); // 官方推荐这种写法
        // Integer 对象转化成 int
        int a = int1.intValue();
        // 字符串转化成 Integer 对象
        Integer int3 = Integer.parseInt("334");
        Integer int4 = new Integer("999");
        // Integer 对象转化成字符串
        String str1 = int3.toString();
        // 一些常见 int 类型相关的常量
        System.out.println("int 能表示的最大整数:" + Integer.MAX_VALUE);
    }
}

自动装箱和拆箱

        自动装箱和拆箱就是将基本数据类型和包装类之间进行自动的互相转换。JDK1.5 后, Java 引入了自动装箱(autoboxing)/拆箱(unboxing)。

自动装箱:

        基本类型的数据处于需要对象的环境中时,会自动转为“对象”。

        我们以 Integer 为例:在 JDK1.5 以前,这样的代码 Integer i = 5 是错误的,必须要通过 Integer i = new Integer(5) 这样的语句来实现基本数据类型转换成包装类的过程; 而在 JDK1.5 以后,Java 提供了自动装箱的功能,因此只需 Integer i = 5 这样的语句就能 实 现 基 本 数 据 类 型 转 换 成 包 装 类 , 这 是 因 为 JVM 为 我 们 执 行 了 Integer i = Integer.valueOf(5)这样的操作,这就是 Java 的自动装箱。

自动拆箱:

        每当需要一个值时,对象会自动转成基本数据类型,没必要再去显式调用 intValue()、doubleValue()等转型方法。

        Integer i = 5;int j = i; 这样的过程就是自动拆箱。

        自动装箱过程是通过调用包装类的 valueOf()方法实现的,而自动拆箱过程是通过调用 包装类的 xxxValue()方法实现的(xxx 代表对应的基本数据类型,如 intValue()、doubleValue() 等)。

        自动装箱与拆箱的功能事实上是编译器来帮的忙,编译器在编译时依据您所编写的语 法,决定是否进行装箱或拆箱动作,

自动装箱:

Integer i = 100;//自动装箱
//相当于编译器自动为您作以下的语法编译:
Integer i = Integer.valueOf(100);//调用的是 valueOf(100),而不是 new Integer(100)

自动拆箱:

Integer i = 100;
int j = i;//自动拆箱
//相当于编译器自动为您作以下的语法编译:
int j = i.intValue();

        所以自动装箱与拆箱的功能是所谓的“编译器蜜糖(Compiler Sugar)”,虽然使用这个功 能很方便,但在程序运行阶段您得了解 Java 的语义。例如示例 8-5 所示的程序是可以通过 编译的:

包装类空指针异常问题:

public class Test {
    public static void main(String[ ] args) {
        Integer i = null;
        int j = i;
    }
}

以上代码相当于如下代码

public class Test {
    public static void main(String[ ] args) {
        Integer i = null;
        int j = i.intValue();
    }

}

        null 表示 i 没有指向任何对象的实体,但作为对象名称是合法的(不管这个对象名称存 是否指向了某个对象的实体)。由于实际上 i 并没有指向任何对象的实体,所以也就不可能 操作 intValue()方法,这样上面的写法在运行时就会出现 NullPointerException 错误。

自动装箱与拆箱:

public class Test {
    public static void main(String[ ] args) {
        Integer b = 23; // 自动装箱
        int a = new Integer(20); //自动拆箱
        Integer c = null;
        int d = c; // 此处其实就是:c.intValue(),因此抛空指针异常。
    }
}

包装类的缓存问题

        整型、char类型所对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存处 理,其目的是提高效率。

        缓存处理的原理为:如果数据在-128~127这个区间,那么在类加载时就已经为该区间的 每个数值创建了对象,并将这256个对象存放到一个名为cache的数组中。每当自动装箱过程 发生时(或者手动调用valueOf()时),就会先判断数据是否在该区间,如果在则直接获取数组中对应的包装类对象的引用,如果不在该区间,则会通过new调用包装类的构造方法来创 建对象。

Integer 类相关源码:

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

这段代码中我们需要解释下面几个问题:

1. IntegerCache类为Integer类的一个静态内部类,仅供Integer类使用。

2. 一般情况下 IntegerCache.low为-128,IntegerCache.high为127,IntegerCache.cache为 内部类的一个静态属性

IntegerCache 类相关源码

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[ ];
    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;
        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }
    private IntegerCache() {}
}

        由上面的源码我们可以看到,静态代码块的目的就是初始化数组cache的,这个过程会 在类加载时完成。

包装类的缓存测试:

public class Test {
    public static void main(String[ ] args) {
        Integer in1 = -128;
        Integer in2 = -128;
        System.out.println(in1 == in2);//true 因为 123 在缓存范围内
        System.out.println(in1.equals(in2));//true
        Integer in3 = 1234;
        Integer in4 = 1234;
        System.out.println(in3 == in4);//false 因为 1234 不在缓存范围内
        System.out.println(in3.equals(in4));//true
    }
}

内存分析图:

JDK1.5 以后,增加了自动装箱与拆箱功能,如:Integer i = 100; int j = new Integer(100);

自动装箱调用的是 valueOf()方法,而不是 new Integer()方法。

自动拆箱调用的 xxxValue()方法。

包装类在自动装箱时为了ᨀ高效率,对于-128~127 之间的值会进行缓存处理。超过范 围后,对象之间不能再使用==进行数值的比较,而是使用 equals 方法。

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

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

相关文章

java 高级面试题(借鉴)(下)

雪花算法原理 第1位符号位固定为0&#xff0c;41位时间戳&#xff0c;10位workId&#xff0c;12位序列号&#xff0c;位数可以有不同实现。 优点&#xff1a;每个毫秒值包含的ID值很多&#xff0c;不够可以变动位数来增加&#xff0c;性能佳&#xff08;依赖workId的实现…

《自动机理论、语言和计算导论》阅读笔记:p1-p4

《自动机理论、语言和计算导论》学习第1天&#xff0c;p1-p4&#xff0c;总计4页。这只是个人的学习记录&#xff0c;因为很多东西不懂&#xff0c;难免存在理解错误的地方。 一、技术总结 1.有限自动机(finite automata)示例 1.software for checking digital circuits。 …

数据结构基础:一篇文章教你单链表(头插,尾插,查找,头删等的解析和代码)

和我一起学编程呀&#xff0c;大家一起努力&#xff01; 这篇文章耗时比较久&#xff0c;所以大家多多支持啦 链表的结构及结构 概念&#xff1a;链表是⼀种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表 中的指针链接次序实现的。 理解&a…

【HarmonyOS】ArkUI - 状态管理

在声明式 UI 中&#xff0c;是以状态驱动视图更新&#xff0c;如图1所示&#xff1a; 图1 其中核心的概念就是状态&#xff08;State&#xff09;和视图&#xff08;View&#xff09;&#xff1a; 状态&#xff08;State&#xff09;&#xff1a;指驱动视图更新的数据&#xf…

Linux安装Nginx及配置TCP负载均衡

目录 1、安装编译工具及库文件2、下载解压Nginx压缩包3、Ngnix配置Tcp负载均衡4、配置Ngnix的文件5、Nginx启动 1、安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c libtool openssl openssl-devel pcre-devel2、下载解压Nginx压缩包 wget https://nginx.o…

腾讯云服务器如何购买?图文全流程,2024最新整理

腾讯云服务器购买流程很简单&#xff0c;有两种购买方式&#xff0c;直接在官方活动上购买比较划算&#xff0c;在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵&#xff0c;但是自定义购买云服务器CPU内存带宽配置选择范围广&#xff0c;活动上购买只能选择固定的活动…

“架构(Architecture)” 一词的定义演变历史(依据国际标准)

深入理解“架构”的客观含义&#xff0c;不仅能使IT行业的系统架构设计师提升思想境界&#xff0c;对每一个积极的社会行动者而言&#xff0c;也具有长远的现实意义&#xff0c;因为&#xff0c;“架构”一词&#xff0c;不只限于IT系统&#xff0c;而是指各类系统(包括社会系统…

ClickHouse部署安装

准备工作 确定防火墙处于关闭状态 CentOS取消打开文件数限制 在hadoop102的 /etc/security/limits.conf文件的末尾加入以下内容 注意&#xff1a;以下操作会修改 Linux 系统配置&#xff0c;如果操作不当可能导致虚拟机无法启动&#xff0c;建议在执行以下操作之前给…

鸿蒙一次开发,多端部署(十五)常见问题

如何查询设备类型 设备类型分为default&#xff08;默认设备&#xff09;、tablet、tv、wearable、2in1等&#xff0c;有多种查询设备类型的方式。 通过命令行的方式查询设备类型。 通过命令行查询指定系统参数&#xff08;const.product.devicetype&#xff09;进而确定设备…

手撕算法-三数之和

描述 分析 排序双指针直接看代码。 代码 public static List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);List<List<Integer>> res new ArrayList<>();for(int k 0; k < nums.length - 2; k){if(nums[k] > 0) break; …

pandas的综合练习

事先说明&#xff1a; 由于每次都要导入库和处理中文乱码问题&#xff0c;我都是在最前面先写好&#xff0c;后面的代码就不在写了。要是copy到自己本地的话&#xff0c;就要把下面的代码也copy下。 # 准备工作import pandas as pd import numpy as np from matplotlib impor…

【Java程序设计】【C00341】基于Springboot的药品管理系统(有论文)

基于Springboot的药品管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 项目获取 &#x1f345;文末点击卡片获取源码&#x1f345; 开发环境 运行环境&#xff1a;推荐jdk1.8&#xff1b; 开发工具&#xff1a;eclipse以及idea&…

修复公众号订阅消息改版金媒v10.3_v10.4和奥壹oelove 10.1处理方式有不同

首先我截图让大家看下自从微信官方弃用历史消息模板改用订阅号消息模板后&#xff0c;两个厂家是怎么针对程序修复的&#xff01; 一.金媒v10.3_v10.4 列出了类目标注了说明&#xff0c;然后参数需要自己申请和对接&#xff0c;对于新手来说一头雾水比较懵&#xff0c;也就是说…

②零基础MySQL数据库-MySQL约束

作用 表在设计的时候加入约束的目的就是为了保证表中的记录完整性和有效性&#xff0c;比如用户表有些列的值&#xff08;手机号&#xff09;不能为空&#xff0c;有些列的值&#xff08;身份证号&#xff09;不能重复 分类 主键约束(primary key) PK 自增长约束(auto_increme…

LabVIEW比例流量阀自动测试系统

LabVIEW比例流量阀自动测试系统 开发了一套基于LabVIEW编程和PLC控制的比例流量阀自动测试系统。通过引入改进的FCMAC算法至测试回路的压力控制系统&#xff0c;有效提升了压力控制效果&#xff0c;展现了系统的设计理念和实现方法。 项目背景&#xff1a; 比例流量阀在液压…

docker desktop 登录不上账号

配置走代理&#xff08;系统全局&#xff09;也没用 解决方法 参考博文&#xff1a; https://blog.csdn.net/weixin_37477009/article/details/135797296 https://adoyle.me/Today-I-Learned/docker/docker-desktop.html 下载 Proxifiler 配置 Proxifiler

使用 Web Components 实现输入法更换皮肤 (vue)

更换皮肤 (界面外观) 是拼音输入法的常见功能. 要实现更换皮肤, 有许多种不同的具体技术方案可以使用. 本文选择 Web Components 技术 (vue) 来实现这个功能. 目录 1 效果展示 1.1 发布新版本 2 Web Components 简介3 vue 使用 Web Components 3.1 使用 vue 实现 Web Compon…

软件测试 -- Selenium常用API全面解答(java)

写在前面 // 如果文章有问题的地方, 欢迎评论区或者私信指正 目录 什么是Selenium 一个简单的用例 元素定位 id定位 xpath定位 name定位 tag name 定位和class name 定位 操作元素 click send_keys submit text getAttribute 添加等待 显示等待 隐式等待 显示等…

立体统计图表绘制方法(分离式环图)

立体统计图表绘制方法&#xff08;分离式环形图&#xff09; 记得我学统计学的时候&#xff0c;那些统计图表大都是平面的框框图&#xff0c;很呆板&#xff0c;就只是表现出统计的意义就好了。在网络科技发展进步的当下&#xff0c;原来一些传统的统计图表都有了进一步的创新。…

uni-app从零开始快速入门

教程介绍 跨端框架uni-app作为新起之秀&#xff0c;在不到两年的时间内&#xff0c;迅速被广大开发者青睐和推崇&#xff0c;得益于它颠覆性的优势“快”&#xff0c;快到可以节省7套代码。本课程由uni-app开发者团队成员亲授&#xff0c;带领大家无障碍快速掌握完整的uni-app…