《Java核心技术》第10版读书笔记之Chap5(4)——基本数据类型的Wrapper类、自动拆箱与装箱及过程中的坑

触摸屏蓝牙控制 使用杰理芯片通过蓝牙实现触摸屏功能,需要结合触摸屏数据采集、蓝牙数据传输以及移动端应用的实现。 阅读详情

Java语言中虽然提供了byte、short、int、long、char、boolean、float、double这些基本数据类型,但由于他们并不是对象,因此有些操作会受到限制,比如不能将其存入容器中等等。为此Java在java.lang包中对于上述每一种基本类型都提供了一个对应的封装类(Wrapper),这些包装类中有一个不可变的对应基本类型的成员变量(也意味着一旦设定就没法更改了)并提供了若干方法。

这里写图片描述

仍然以Integer为例,看看Wrapper类型都提供了哪些功能:

1.字符串与基本数据类型的互转:XX.parseXX方法与XX.toString(XX)静态方法

这里写图片描述

需要注意的是,待转换的字符串必须符合对应类型的规定,否则在运行期会抛出解析错误的异常:

    public static void main(String[] args) {
        int n1 = Integer.parseInt("666666");
        int n2 = Integer.parseInt("-666666");
        int n3 = Integer.parseInt("  2333333");
        System.out.println(n1);
        System.out.println(n2);
    }

在这段代码中,n1和n2能被正常解析出来,但在执行Integer.parseInt(” 2333333”)时,由于输入的字符串中包含空格,其不能解释为数字,所以发生异常:

Exception in thread "main" java.lang.NumberFormatException: For input string: "  2333333"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Integer.parseInt(Integer.java:569)
    at java.lang.Integer.parseInt(Integer.java:615)
    at CMain.main(CMain.java:11)

此外,Integer类还有一个重载的parseInt方法,输入的是字符串和进制数,字符串里的内容会被按照对应的进制数解析,如下列代码的运行结果就为16:

    public static void main(String[] args) {
        int n1 = Integer.parseInt("1100", 2);
        System.out.println(n1);
    }

另外,将基本数据类型转换为字符串的方法之前的文章已经提到过了,直接用”” + 的方式即可,即用空串连接上一个基本数据类型即可。当然,也可以选择使用Integer.toString(int)方法,该方法为静态方法,会返回对应基本类型的字符串表示。

    public static void main(String[] args) {
        String s1 = Integer.toString(23);
        String s2 = Integer.toString(23, 2);
        String s3 = "" + 233;

        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
    }
//对应的结果分别是:
//23
//10111
//233

对于Integer类型,还有如下静态方法可供调用:

  • 进制转换toBinaryString(int)方法
  • toHexString(int)
  • toOctalString(int)

2.构造方法

以int类型对应的Integer封装类为例,其源码中有如下片段:

    public final class Integer extends Number implements Comparable<Integer> {   
       //......
       private final int value;

       public Integer(int value) {
           this.value = value;
       }
       //......
       public Integer(String s) throws NumberFormatException {
           this.value = parseInt(s, 10);
       }
   }

从中可以看出如下几点:

  1. Wrapper类为final类型
  2. 其中封装的基本类型也标明为final,意味着对象一旦创建,其表征的值就不能再被更改了
  3. 可以用基本数据类型或字符串的方式构建一个对应的Wrapper对象

3.intValue方法:返回封装的基本数据类型。

   public static void main(String[] args) {
           Integer n1 = new Integer("23333");
           int n = n1.intValue();
           System.out.println(n);
   }

4.MAX_VALUE与MIN_VALUE静态成员变量:最大值与最小值

这一点没有太多要说的,直接看Integer类的源码就知道了:

@Native public static final int   MIN_VALUE = 0x80000000;
@Native public static final int   MAX_VALUE = 0x7fffffff;

5.自动装箱与自动拆箱——带着坑的语法糖

  • 自动装箱:将基本数据类型赋值给Wrapper类,下面两条语句其实是等价的。
  • 自动拆箱:将Wrapper类中的数据返回给基本数据类型

       public static void main(String[] args) {
           Integer n1 = Integer.valueOf(333);
           Integer n2 = 333;
       }

正是因为有了javac编译器的自动装拆箱,才使得我们可能写出这样的代码:

ArrayList arrayInteger = new ArrayList<Integer>;
arrayInteger.add(13);
Integer n1 = 32;
n1 = n1 + 233;

这里的13在加入arrayInteger中时会自动装箱,成为Integer类型。同理,n1也经过了自动装箱,成为了Integer类型。而当执行n1 + 233操作时,有需要对n1进行自动拆箱,加法运算结束后再通过自动装箱重新变回了Integer类型。

但是也需要注意,这种自动装拆箱机制是有弊端的:

  1. 每一次装箱都伴随着对象的创建,会耗费时空资源

  2. 对null的Wrapper类对象执行自动拆箱,会引发空引用异常。所以,尽量不要把Wrapper类对象引用设为null,宁可让其值为0。

    Integer n3 = null;
    n3 = n3 + 233;
    /*上述代码执行时将引发如下异常:
    Exception in thread "main" java.lang.NullPointerException
    at CMain.main(CMain.java:12)*/
  3. Wrapper类型对象的值缓存机制

    Integer类的valueOf静态成员方法源码如下:

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

    而其中的IntegerCache是Integer类的内部类。

    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() {}
       }

    可以看出,在该类中确实有缓存,且该缓存至少覆盖了[-128, 127]这个区间范围。所以,当自动装箱机制使用valueOf()方法时,在该区间范围内的数变会使用缓存里的实例,返回的也是这些缓存实例的引用。但是要注意,如果不使用自动装箱机制,而是直接new Integer(2)之类的方法创建对象,则不会有任何的缓存机制。

    这点我印象十分深刻:曾经在做一个项目的时候,没有看清楚其Bean类中用的是Integer而非int,结果单测时用的数据是小于127的,没有发现问题。上线后,使用一段时间后用户反馈出现问题,检查后分析就是栽在了这个所谓的缓存机制上。

      public static void main(String[] args) {
           Integer n1 = 127;
           Integer n2 = 127;
           System.out.println(n1 == n2);
           System.out.println(n1.equals(n2));
    
           System.out.println("---------------------------------");
    
           Integer n3 = 128;
           Integer n4 = 128;
           System.out.println(n3 == n4);
           System.out.println(n3.equals(n4));
    
           System.out.println("---------------------------------");
    
           Integer n5 = new Integer(127);
           Integer n6 = new Integer(127);
           System.out.println(n5 == n6);
           System.out.println(n5.equals(n6));
       }

    三组测试的结果分别是:

    true
    true
    
    false
    true
    
    false
    true

    所以,在Java中,对127以内的Byte、Short、Integer、Long对应的基本数据类型进行自动装箱,会从内建的缓存数组中引用同一个对象,而从128开始则不再使用这种缓存机制。另外这种缓存机制仅限于自动装箱的情况,对于显示new出的对象则无此机制。

【100%通过率】华为OD机试真题 Python【数字最低位排序】【最低位排序】 2023华为OD机试真题 Python【数字最低位排序】【最低位排序】 给定一个非空数组(列表) 起元素数据类型为整型 请按照数组元素十进制最低位从小到大进行排序 十进制最低位相同的元素,相对位置保持不变 当数组元素为负值时,十进制最低为等同于去除符号位后对应十进制值最低位 阅读详情

相关推荐

继电器的选型规范

触点是继电器中最重要的结构件,触点的使用寿命受触点材料、触点上的电压及电流值(特别是接通时及断开时的电压、电流波形)、负载种类、切换频率、环境情况、接触形式、触点回跳现象等的影响,触点失效多以触点的材料转移、粘连、异常消耗、接触电阻增大等故障现象出现,使用时需要注意。为了稳定工作, DC 型继电器的线圈两端所加电压推荐使用波纹变化率小于±5%的线圈额定电压,否则继电器会工作不稳定,引起触点的粘接或异常损耗,特别是在继电器的驱动电路上连接有电动机、螺线管、变压器等器件时,这种情况更为明显。

qq_43416206的博客 1879

WPF 渲染原理

对于开发者来说,WPF 中最主要的知识点就是渲染,因为 WPF 是一个界面框架。想用一篇博客就能告诉大家完整的 WPF 渲染原理是不可能的。本文向大家介绍从开发者执行绘图...

dotNET跨平台 2147

Nmap的介绍、安装 并进行网络扫描

Nmap概述 Nmap(Network Mapper(网络映射器))是一个网络连接端扫描软件,用来扫描网上电脑开放的网络连接端。确定哪些服务运行在哪些连接端,并且推断计算机运行哪个操作系统(这是亦称 fingerprinting)。它是网络管理员必用的软件之一,以及用以评估网络系统安全。 正如大多数被用于网络安全的工具,nmap 也是不少黑客及骇客(又称脚本小子)爱用的工具 。系统管理员可以利用nmap来探测工作环境中未经批准使用的服务器,但是黑客会利用nmap来搜集目标电脑的网络设定,从而计划攻击的方法。

Cheney ' blog 2万+

从多项式到神经网络:DPD算法演进史及其在RRU中的工程实现

本文系统梳理了数字预失真(DPD)算法从经典多项式模型、查表法到神经网络驱动的演进历程,并深入探讨了其在基站射频单元(RRU)中面临的硬件资源约束与工程实现挑战。文章为通信设备的技术决策者提供了算法选型、性能权衡及混合架构设计的实用评估框架,助力在性能、功耗与成本间找到最优平衡。

cherry的博客 1075

Docker容器化部署Ceph集群:从零搭建高可用分布式存储

本文详细介绍了如何使用Docker容器化部署Ceph集群,从零搭建高可用分布式存储系统。通过环境一致性、快速扩容和资源隔离等优势,Docker显著提升了Ceph集群的部署效率和运维便捷性。文章涵盖硬件规划、镜像选择、单节点部署、多节点扩展及性能调优等实战内容,帮助开发者快速掌握分布式存储系统的容器化部署技巧。

weixin_29081101的博客 422

Exception in thread “main“ java.lang.NullPointerException出现空指针

在对xml进行解析时问题出现了问题出现是空指针。。。这个错误常见于试图对一个空对象进行操作。根据错误提示,可以看出错误发生在Main.java文件的第 15 行。在这一行中,试图解析一个 XML 文件,但是可能文件不存在或无法找到。如果文件不存在,可以尝试检查文件路径是否正确。如果文件路径正确,文件可能已被移动、删除或重命名,可以确认文件是否可用。如果您确认文件存在,那么可能出现了其他问题,您可以尝试检查Jsoup库是否已正确导入,并且没有其他相关依赖项缺失或损坏。通常存在的问题是。

qq_52615472的博客 1035

springboot+vue项目基础开发(12)vue项目的搭建

在src目录下新建 api,utils,views文件夹。删除componets目录下自动生成的所有文件。在utils文件夹下创建request.js。启动项目,记得是要在管理员下启动。

m0_58498702的博客 152

Exception in thread “main“ java.lang.NullPointerException java报空指针异常

空指针异常产生的主要原因如下: (1)当一个对象不存在时又调用其方法会产生异常obj.method() // obj对象不存在 (2)当访问或修改一个对象不存在的字段时会产生异常obj.method() // method方法不存在 (3)字符串变量未初始化; (4)接口类型的对象没有用具体的类初始化,比如: List lt;会报错 List lt = new Arra

leo 8万+

【unity游戏开发之InputSystem——01】通过写代码监听InputSystem输入(基于unity6开发介绍)

通过写代码监听InputSystem输入(基于unity6开发介绍)

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 4890

热力学仿真软件:ANSYS CFX_(15).旋转机械仿真

创建旋转域在中选择需要设置为旋转域的区域。选择选项。设置旋转速度在设置中,指定旋转速度(单位为弧度/秒)。也可以选择选项,并输入具体值。设置旋转轴在设置中,指定旋转轴的方向和位置。通常旋转轴的方向可以使用单位向量来表示,例如[0, 0, 1]表示沿Z轴旋转。旋转轴的位置可以通过指定一个点的坐标来确定,例如[0, 0, 0]表示旋转轴通过原点。旋转机械的仿真在ANSYS CFX中是一个复杂但重要的过程。

kkchenjj的博客 1157

猫头虎分享已解决Bug | Java Error: Exception in thread ‘main‘ java.lang.NullPointerException

大家好,我是猫头虎博主,今天带大家深入探索一个后端技术领域的常见Bug - Java中的。这个问题像是一只调皮的小猫,常在你不经意间跳出来捣乱。我们将探讨这个问题的成因、解决方案,以及如何优雅地避免它。准备好了吗?让我们开始这次的技术之旅吧!错误类型原因解决方法防范措施对象未初始化确认初始化使用Optional方法返回null检查返回值校验外部数据类成员变量未赋值初始化成员变量使用注解在Java编程中,是一种常见但可以避免的错误。

深入 IT 各领域的角落,分享前沿技术见解与实践心得。与我一起,探索技术的无限可能! 1856

从零开始跑通3DGS教程:(三)坐标系与尺度编辑(CloudCompare)

本文所属《从零开始跑通3DGS教程》系列文章; sfm重建的点云已经丢掉了尺度信息,并且坐标系跟图像数据有关(SFM初始化选择的图像),所以如果想恢复物理真实尺度,以及在想要的视角下渲染,那么需要对尺度和坐标系进行编辑修正,下文介绍如何使用CloudCompare修改坐标系和尺度

诺有缸的高飞鸟的博客 2870

Wrapper配置详解及高级应用

        将一个简单的程度如HelloWorld 的应用包装秤Wrapper 服务并不复杂,甚至可以认为非常简单。但是实际项目应用过程中我们的程序一般较庞大,运行环境也较复杂。         通过Wrapper 配置文件的分析与配置进一步了解构建Wrapper 服务需要注意的关键点及重要部分。 首先,打开conf 文件夹下的wrapper.conf配置文件,此配置文件时Wrappe...

286 2168

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

基本数据类型的包装类(wrapper class)、自动的装箱和拆箱、时间处理相关类、Math类、File类、枚举类...

包装类(wrapper class)   --基本数据类型对应的类统称为包装类(WrapperClass)。包装类均位于java.lang包,包装类和基本数据类型的对应关系如下表所示: 基本数据类型 包装类 byte Byte short Short int Integer long Long float F...

aiu5949的博客 194

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

VC 获取任务栏窗体的句柄

 本文将介绍一个未公开的Win32 API函数:GetTaskmanWindow。利用它对Windows的任务栏进行操作。这个函数返回拥有任务栏button的窗体句柄。在微软的MSDN文档中。对任务栏是这样描写叙述的:"……Windows界面包括一个特殊的应用程序桌面工具栏,叫做任务栏。任务栏能够用于在打开的不同窗体之间进行切换,以及启动新的应用程序……。任务栏包括有開始菜单、任务栏...

weixin_30735391的博客 682

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Java integer.parseInt()与 integer.valueof()

integer.parseInt() (此节参考:https://www.cnblogs.com/flord/p/6056969.html) public static int parseInt(String s, int radix) 以第二个参数所指定基数将字符串参数分析为一个带符号的整数,其返回作为结果的整数值。返回值为int类型。 public static int parseIn...

一个潜心学习的小白 3915

时间转换报java.lang.NumberFormatException: multiple points问题

最近项目一直会出现时间转换报错,一直不知道是什么问题, java.lang.NumberFormatException: multiple points     at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1110)     at java.lang.Double.parseDouble(Doub

zhongyangjian的专栏 1万+

java不能对什么类型进行转换_@Value - >无法将类型'java.lang.String'的值转换为所需类型'java.lang.Integer'...

美好的一天,我正在使用Spring 4.1.1.RELEASE开发一个Web应用程序。所有Spring的配置与注解来实现,它工作得很好,除了一两件事:@Value - >无法将类型'java.lang.String'的值转换为所需类型'java.lang.Integer'我与这些行项目config.properties文件 cases.caseList.filter=testcases.ca...

weixin_30047059的博客 2521

内存溢出案例分析

[b]集群间同步导致内存溢出[/b] JBossCache的JGroups进行通信。保证各个数据节点的数据同步。主要故障一般出现在网络不稳定的情况下,会有大量的同步重发数据在协议栈中积累。当并发量大的时候,加之网络不稳定,就会在内存中堆积过多导致溢出。 [b]堆外内存导致的溢出错误[/b] cometD1.1.1框架,有大量的NIO操作,需要用大豆哦Direct Memory。容易造成堆...

报喜鸟 264

java中Integer值比较不注意的问题

今天,帮人看代码时,发现这个问题,回顾起来,记录下来。 先来看一个代码片段 [java] view plain copy public static void main(String[] args) { Integer a1 = Integer.valueOf(60); //danielinbiti Integer b1 = 60; Sy

苍漠胡杨 1891

《Java 核心技术卷1 第10版》学习笔记------ 对象包装器、自动装箱、拆箱

    有时, 需要将 int 这样的基本类型转换为对象。 所有的基本类型都冇一个与之对应的类。例如,Integer 类对应基本类型 int。通常, 这些类称为包装器 ( wrapper ) 这些对象包装器类拥有很明显的名字:Integer、Long、Float、Double、Short、Byte、Character 、Void 和 Boolean (前6 个类派生于公共的超类 Number)。对...

FKNIGHT 的博客 352

Java核心技术 读书笔记——思维导图版本

Java核心技术 读书笔记

qq_36914676的博客 796
上一篇: 《Java核心技术》第10版读书笔记之Chap5(3)——Object类及其equals、hashCode与toString方法
下一篇: 《Java核心技术》第10版读书笔记之Chap5(5)——Java中变参函数以及枚举类的原理与使用
LPWSTR
博客等级 码龄10年 73粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值