【java】java基本类型和包装类型的区别

news2025/7/20 21:22:30

文章目录

  • 简介
  • 1.包装类型可以为 null,而基本类型不可以
  • 2.包装类型可用于泛型,而基本类型不可以
  • 3.基本类型比包装类型更高效
  • 4.自动装箱和自动拆箱

简介

Java 的每个基本类型都对应了一个包装类型,比如说 int 的包装类型为 Integer,double 的包装类型为 Double。基本类型和包装类型的区别主要有以下 4 点

1.包装类型可以为 null,而基本类型不可以

它使得包装类型可以应用于 POJO 中,而基本类型则不行
POJO:简单无规则的 Java 对象,只有属性字段以及 setter 和 getter 方法,示例如下。

class Writer {
    private Integer age;
    private String name;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

为什么 POJO 的属性必须要用包装类型?
《阿里巴巴 Java 开发手册》上有详细的说明

数据库的查询结果可能是 null,如果使用基本类型的话,因为要自动拆箱(将包装类型转为基本类型,比如说把 Integer 对象转换成 int
值),就会抛出 NullPointerException 的异常。

2.包装类型可用于泛型,而基本类型不可以

泛型不能使用基本类型,因为使用基本类型时会编译出错。

List<int> list = new ArrayList<>();
 // 提示 Syntax error, insert "Dimensions" to complete ReferenceType
List<Integer> list = new ArrayList<>();

3.基本类型比包装类型更高效

基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用
在这里插入图片描述

相比较于基本类型而言,包装类型需要占用更多的内存空间。假如没有基本类型的话,对于数值这类经常使用到的数据来说,每次都要通过 new 一个包装类型就显得非常笨重。
两个包装类型的值可以相同,但却不相等

Integer chenmo = new Integer(10);
Integer wanger = new Integer(10);

System.out.println(chenmo == wanger); // false
System.out.println(chenmo.equals(wanger )); // true

两个包装类型在使用“==”进行判断的时候,判断的是其指向的地址是否相等。将“==”操作符应用于包装类型比较的时候,其结果很可能会和预期的不符。

4.自动装箱和自动拆箱

有了基本类型和包装类型,肯定有些时候要在它们之间进行转换。
把基本类型转换成包装类型的过程叫做装箱。
反之,把包装类型转换成基本类型的过程叫做拆箱
在 Java SE5 之前,开发人员要手动进行装拆箱

Integer chenmo = new Integer(10);  // 手动装箱
int wanger = chenmo.intValue();  // 手动拆箱

Java SE5 为了减少开发人员的工作,提供了自动装箱与自动拆箱的功能

Integer chenmo  = 10;  // 自动装箱
int wanger = chenmo;     // 自动拆箱

等价于=>

Integer chenmo = Integer.valueOf(10);
int wanger = chenmo.intValue();

也就是说,自动装箱是通过Integer.valueOf()完成的;自动拆箱是通过 Integer.intValue() 完成的
特别注意:

当需要进行自动装箱时,如果数字在 -128 至 127 之间时,会直接使用缓存中的对象,而不是重新创建一个对象

// 1)基本类型和包装类型
int a = 100;
Integer b = 100;
System.out.println(a == b);//true

// 2)两个包装类型
Integer c = 100;
Integer d = 100;
System.out.println(c == d);//true

// 3)
Integer c = 200;
Integer d = 200;
System.out.println(c == d);//false

答案是什么呢?

第一段代码,基本类型和包装类型进行 == 比较,这时候 b 会自动拆箱,直接和 a 比较值,所以结果为 true。

第二段代码,两个包装类型都被赋值为了 100,这时候会进行自动装箱,那 == 的结果会是什么呢?

我们之前的结论是:将“==”操作符应用于包装类型比较的时候,其结果很可能会和预期的不符。那结果是 false?但这次的结果却是 true,是不是感觉很意外?

第三段代码,两个包装类型重新被赋值为了 200,这时候仍然会进行自动装箱,那 == 的结果会是什么呢?false

分析源码。
之前我们已经知道了,自动装箱是通过 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 在作怪?你猜对了!

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;
        int i = parseInt(integerCacheHighPropValue);
        i = Math.max(i, 127);
        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
        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;
    }
}

大致瞟一下这段代码你就全明白了。-128 到 127 之间的数会从 IntegerCache 中取,然后比较,所以第二段代码(100 在这个范围之内)的结果是 true,而第三段代码(200 不在这个范围之内,所以 new 出来了两个 Integer 对象)的结果是 false。

看完上面的分析之后,我希望大家记住一点:当需要进行自动装箱时,如果数字在 -128 至 127 之间时,会直接使用缓存中的对象,而不是重新创建一个对象。

自动装拆箱是一个很好的功能,大大节省了我们开发人员的精力,但也会引发一些麻烦,比如下面这段代码,性能就很差。

long t1 = System.currentTimeMillis();
Long sum = 0L;
for (int i = 0; i < Integer.MAX_VALUE;i++) {
    sum += i;
}
long t2 = System.currentTimeMillis();        
System.out.println(t2-t1);

sum 由于被声明成了包装类型 Long 而不是基本类型 long,所以 sum += i 进行了大量的拆装箱操作(sum 先拆箱和 i 相加,然后再装箱赋值给 sum),导致这段代码运行完花费的时间足足有 2986 毫秒;如果把 sum 换成基本类型 long,时间就仅有 554 毫秒,完全不一个等量级。

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

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

相关文章

ECOLOY直接更换流程表单后导致历史流程中数据为空白的解决方案

用户反馈流历史流程打开是空白了没有内容。 一、问题调查分析&#xff1a; 工作流“XX0204 员工培训协议审批流程”workflowId37166产生的7个具体流程中&#xff0c;创建日期为2021年的4个具体流程原先引用的数据库表单应该是“劳动合同签订审批表”(formtable_main_190)&…

JavaScript-缓存

参考资料彻底解决让用户清一下浏览器缓存浏览器缓存彻底理解浏览器的缓存机制彻底弄懂前端缓存浅解强缓存和协商缓存浏览器缓存策略(强缓存和协商缓存)一文搞定Http缓存-强制缓存与协商缓存前端浏览器缓存知识梳理ASP.NET Core 中使用缓存IIS中设置Cache-Control是什么当我们第…

[Gin]框架底层实现理解(一)

前言&#xff1a;路由原理———压缩字典 这边简单讲一下gin非常重要的一个基点&#xff0c;也就是他作为go web框架的一个亮点 也就是Trie树和压缩字典算法 gin 通过树来存储路由&#xff0c;讲路由的字符拆解为一个个的结点&#xff0c;在获取handler函数时&#xff0c;会…

项目管理系统软件有哪些?这10款最好用的项目管理软件值得推荐

项目管理系统软件有哪些&#xff1f;这10款好用的项目管理系统软件值得推荐 如今企业规模不断扩大&#xff0c;业务逐渐复杂化&#xff0c;项目管理系统已经成为现代企业管理中不可或缺的一环&#xff1b; 而项目管理系统软件不仅可以保证项目按时完成&#xff0c;提高团队的…

【Java基础 下】 029 -- 多线程

目录 一、为什么要有多线程&#xff1f; 1、线程与进程 2、多线程的应用场景 3、小结 二、多线程中的两个概念&#xff08;并发和并行&#xff09; 1、并发 2、并行 3、小结 三、多线程的三种实现方式 1、继承Thread类的方式进行实现 2、实现Runnable接口的方式进行实现 3、利用…

MySQL简述

一、什么是数据库 数据库&#xff08;DB&#xff0c;DataBase&#xff09; 概念&#xff1a;数据仓库&#xff0c;相当于一款软件&#xff0c;安装在操作系统&#xff08;Windows&#xff0c;Linux&#xff0c;mac&#xff0c;…&#xff09;之上&#xff0c;可以存储大量的数…

nvm安装及使用(win)

一、安装nvm 下载地址&#xff1a;下载之后安装包安装 安装路径不要有中文或者空格 安装时尽量不要选择系统盘&#xff08;安装在系统盘可能会涉及到权限问题&#xff09; 安装前一定要把 node 的环境变量和 npm 的环境变量删除&#xff0c;否则在切换 node 版本时会报错 二、…

SCL_PFENET跑通填坑

1.数据准备&#xff1a;VOC2012数据集&#xff0c;initmodel文件夹&#xff08;预训练模型&#xff09;&#xff0c;SegmentationClassAug数据2.训练部分&#xff1a;训练部分没什么需要改动的&#xff0c;也就改一下选择的配置文件。在config文件夹里有关于coco和voc数据的配置…

备战蓝桥杯Day3python——迭代器的使用

python封装的迭代器 我们接下来介绍用于返回笛卡尔积的Permutations函数 Permutations(iterator, r) r:表示进行迭代后返回的长度 实例&#xff1a; >>> from itertools import permutations >>> a abc >>> for i in permutations(a,3):print …

Java深拷贝,浅拷贝

一、浅拷贝&#xff1a; &#xff08;1&#xff09; 对于数据类型是基本数据类型的成员变量&#xff0c;浅拷贝会直接进行值传递&#xff0c;也就是将该属性复制一份给新的对象。因为是两份不同的数据&#xff0c;所以对其中一的对象的成员变量值进行修改&#xff0c;不会影响另…

大考在即 百度版ChatGPT会翻车吗?

文心一言的发布会定档3月16日&#xff0c;不出意外&#xff0c;百度创始人李彦宏、CTO王海峰将出现在北京总部的发布会现场。这是百度版ChatGPT最新的官方消息&#xff0c;2月7日&#xff0c;文心一言首次官宣&#xff0c;当时称&#xff0c;产品“3月见”。 3月如期而至&…

C语言再学习 -- __attribute__详解

一、attribute 介绍 __attribute__是一个编译属性&#xff0c;用于向编译器描述特殊的标识、错误检查或高级优化。它是GNU C特色之一&#xff0c;系统中有许多地方使用到。__attribute__可以设置函数属性&#xff08;Function Attribute&#xff09;、变量属性&#xff08;Var…

JavaScript 如何优雅地获取多层级response中的某个深层次字段 ?. 可选链条(Optional chaining)

文章目录一句话场景&#xff1a;从一个多层级对象中拿一个处在深层次位置的字段MDN 可选链搜索引擎使用一句话 var marriedFlag response.data.userList[0].married; // 如果中间某个对象为空&#xff0c;会报Errorvar marriedFlag response?.data?.userList[0]?.married…

外贸新手找客户的开发信修炼之旅(一)

开发信是一种传统的开发海外客户的方式&#xff0c;相信即便是外贸新手也或多或少有所耳闻&#xff0c;甚至已经通过邮件开发到了一些有意向的客户&#xff0c;但有时也会遇到开发信效果不好的情况&#xff0c;收到的回复寥寥无几。其实说白了开发信的本质与派发传单相同&#…

李开复已经对美图公司失去耐心,并在美图公司身上损失惨重

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经经过对美图公司&#xff08;01357&#xff09;的投资人回报、产品、业务结构、战略、财务业绩、估值等方面进行了研究&#xff0c;认为美图这家公司不行&#xff0c;非常不看好&#xff0c;以下是理由供你参考。一…

10 Seata配置Nacos注册中心和配置中心

Seata配置Nacos注册中心和配置中心 Seata支持注册服务到Nacos&#xff0c;以及支持Seata所有配置放到Nacos配置中心&#xff0c;在Nacos中统一维护&#xff1b; 高可用(集群)模式下就需要配合Nacos来完成: 具体配置如下 注册中心 Seata-server端配置注册中心&#xff0c;…

【洛谷 P1219】[USACO1.5]八皇后 Checker Challenge 题解(深度优先搜索+回溯法)

[USACO1.5]八皇后 Checker Challenge 题目描述 一个如下的 666 \times 666 的跳棋棋盘&#xff0c;有六个棋子被放置在棋盘上&#xff0c;使得每行、每列有且只有一个&#xff0c;每条对角线&#xff08;包括两条主对角线的所有平行线&#xff09;上至多有一个棋子。 上面的布…

13_MySQL中的约束

目录 1. 约束(constraint)概述 1.1 为什么需要约束 1.2 什么是约束 1.3 约束的分类 2. 非空约束 2.1 作用 2.2 关键字 2.3 特点 2.4 添加非空约束 2.5 删除非空约束 3. 唯一性约束 3.1作用 3.2 关键字 3.3 特点 3.5 关于复合唯一约束 4. 主键(PRIMARY KEY)约束 4.1 作用 4.2 关…

【Django】Hello,DJango!

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…

如何实现报表可视化,有没有工具推荐

随着数据量的不断增长&#xff0c;如何更好地进行数据分析和可视化已成为企业和组织面临的重要挑战。实现报表可视化是一个很好的解决方案&#xff0c;它可以帮助用户更好地理解和分析数据&#xff0c;发现趋势和模式&#xff0c;并支持数据驱动的决策。本文将介绍如何实现报表…