面试官:兄弟,说说基本类型和包装类型的区别吧

article/2025/9/24 4:00:12

六年前,我从苏州回到洛阳,抱着一幅“海归”的心态,投了不少简历,也“约谈”了不少面试官,但仅有两三个令我感到满意。其中有一位叫老马,至今还活在我的手机通讯录里。他当时扔了一个面试题把我砸懵了:说说基本类型和包装类型的区别吧。

我当时二十三岁,正值青春年华,从事 Java 编程已有 N 年经验(N < 4),自认为所有的面试题都能对答如流,结果没想到啊,被“刁难”了——原来洛阳这块互联网的荒漠也有技术专家啊。现在回想起来,脸上不自觉地泛起了羞愧的红晕:主要是自己当时太菜了。不管怎么说,是时候写篇文章剖析一下基本类型和包装类型的区别了。

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

01、包装类型可以为 null,而基本类型不可以

别小看这一点区别,它使得包装类型可以应用于 POJO 中,而基本类型则不行。

POJO 是什么呢?这里稍微说明一下。

POJO 的英文全称是 Plain Ordinary Java Object,翻译一下就是,简单无规则的 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 类似的,还有数据传输对象 DTO(Data Transfer Object,泛指用于展示层与服务层之间的数据传输对象)、视图对象 VO(View Object,把某个页面的数据封装起来)、持久化对象 PO(Persistant Object,可以看成是与数据库中的表映射的 Java 对象)。

那为什么 POJO 的属性必须要用包装类型呢?

《阿里巴巴 Java 开发手册》上有详细的说明,我们来大声朗读一下(预备,起)。

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

02、包装类型可用于泛型,而基本类型不可以

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

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

为什么呢?因为泛型在编译时会进行类型擦除,最后只保留原始类型,而原始类型只能是 Object 类及其子类——基本类型是个特例。

03、基本类型比包装类型更高效

基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。

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

03、两个包装类型的值可以相同,但却不相等

两个包装类型的值可以相同,但却不相等——这句话怎么理解呢?来看一段代码就明明白白了。

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

两个包装类型在使用“”进行判断的时候,判断的是其指向的地址是否相等。chenmo 和 wanger 两个变量使用了 new 关键字,导致它们在“”的时候输出了 false。

chenmo.equals(wanger) 的输出结果为 true,是因为 equals 方法内部比较的是两个 int 值是否相等。源码如下。

private final int value;public int intValue() {return value;
}
public boolean equals(Object obj) {if (obj instanceof Integer) {return value == ((Integer)obj).intValue();}return false;
}

瞧,虽然 chenmo 和 wanger 的值都是 10,但他们并不相等。换句话说就是:将“==”操作符应用于包装类型比较的时候,其结果很可能会和预期的不符

04、自动装箱和自动拆箱

既然有了基本类型和包装类型,肯定有些时候要在它们之间进行转换。把基本类型转换成包装类型的过程叫做装箱(boxing)。反之,把包装类型转换成基本类型的过程叫做拆箱(unboxing)。

在 Java SE5 之前,开发人员要手动进行装拆箱,比如说:

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

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

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

上面这段代码使用 JAD 反编译后的结果如下所示:

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

也就是说,自动装箱是通过 Integer.valueOf() 完成的;自动拆箱是通过 Integer.intValue() 完成的。理解了原理之后,我们再来看一道老马当年给我出的面试题。

// 1)基本类型和包装类型
int a = 100;
Integer b = 100;
System.out.println(a == b);// 2)两个包装类型
Integer c = 100;
Integer d = 100;
System.out.println(c == d);// 3)
c = 200;
d = 200;
System.out.println(c == d);

答案是什么呢?有举手要回答的吗?答对的奖励一朵小红花哦。

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

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

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

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

吃了第二段代码的亏后,是不是有点怀疑人生了,这次结果是 true 还是 false 呢?扔个硬币吧,哈哈。我先告诉你结果吧,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 propertyint 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 毫秒,完全不一个等量级啊。

05、最后

谢谢大家的阅读,原创不易,喜欢就点个赞,这将是我最强的写作动力。如果你觉得文章对你有所帮助,也蛮有趣的,就关注一下我的公众号,谢谢。


http://chatgpt.dhexx.cn/article/mISHIa1Y.shtml

相关文章

【一些好听的英文歌曲】

原文地址&#xff1a;【一些好听的英文歌曲】 作者&#xff1a;姑娘我笑着活 1、Bubbly--Colbie Caillat&#xff08;你听过一遍就会非常喜欢的歌&#xff09;&#xff1b; 2、Burning--Maria Arredondo&#xff1b; 3、Happy--丽安娜 刘易斯&#xff1b; 4、Cry On My Shoulde…

彻底理解position与anchorPoint - 记忆丶腐朽年华

引言 相信初接触到CALayer的人都会遇到以下几个问题&#xff1a; 为什么修改anchorPoint会移动layer的位置&#xff1f; CALayer的position点是哪一点呢? anchorPoint与position有什么关系&#xff1f; 我也迷惑过&#xff0c;找过网上的教程&#xff0c;大部分都是复制粘…

每日一句英语珍句

2016/11/06 Our lives are brief, thats why its important to search for meaning. 人的一生如此短暂,因此,找到活着的意义至关重要。 ------《绝望主妇》 2016/11/06 Life is like a multiple choice question. Sometimes, the choices confuse you, …

2019年感:忆往昔考博岁月,看今朝花样年华

人生的际遇谁又能说清楚&#xff0c;就像师范类毕业的女神梦想着当一名老师&#xff0c;结果却阴差阳错穿上了警服&#xff1b;而本应该奔波北上广深的程序员&#xff0c;却成为了一名大学老师&#xff0c;两条平行线的男女&#xff0c;却结为了连理。再如&#xff0c;一心准备…

英语年华的空间

学习前预热&#xff1a; ———轻松学英语第一步&#xff1a;建立英语思维 为什么大家学英语学得这么累&#xff0c;最后依然对英语糊糊涂涂&#xff1f;原因只有一个——就是我们的学习能力太差了&#xff01;&#xff01;我们的老师太笨了&#xff01;&#xff01;&#xf…

Wireshark切割PCAP以及合并PCAP

1 Wireshark切割PCAP 有时候对PCAP包进行分析&#xff0c;会遇到内存不足打不开较大的PCAP&#xff0c;那么有两种方法解决这个问题&#xff0c;一个是写程序对PCAP进行过滤或者截取&#xff1b;另一个是使用Wireshark自带的函数进行PCAP切割&#xff0c;本篇选择使用Wireshar…

SplitCap切分pcap包

SplitCap下载 SplitCap 是一款免费工具&#xff0c;旨在根据 IP 地址、5 元组或 MAC 地址等标准将捕获文件&#xff08;PCAP 文件&#xff09;拆分为较小的文件。下载地址&#xff1a;SplitCap Windows下使用 下载完SplitCap后&#xff0c;可以在windows终端中直接使用&…

pcap文件的python解析实例

最近一直在分析数据包。 同时也一直想学python。 凑一块儿了...于是&#xff0c;便开工了。座椅爆炸&#xff01; 正文首先要说的是&#xff0c;我知道python有很多解析pcap文件的库&#xff0c;这里不使用它们的原因是为了理解pcap文件的格式细节。使用tcpdump你可以很容易抓…

CapAnalysis Pcap分析工具

CapAnalysis Pcap分析工具&#xff1a; CapAnalysis 对 PCAP 文件的数据集进行索引并以多种形式呈现它们的内容&#xff0c;从 TCP、UDP 或 ESP 流/流列表开始&#xff0c;传递到连接的地理表示。对于由一个或多个 PCAP 文件组成的每个数据集&#xff0c;CapAnalysis 收集数据…

wirehark数据分析与取证misc1.pcap

什么是wireshark&#xff1f; wiresharekwireshark--misc1.pcap数据包 wiresharek Wireshark&#xff08;前称Ethereal&#xff09;是一个网络封包分析软件。网络封包分析软件的功能是检索取网络封包&#xff0c;并同时显示出最详细的网络封包数据。Wireshark使用WinPCAP作为接…

.pcapng文件格式和.pcap文件格式

原网页 本文为机翻后人工修饰了一些&#xff0c;总结一句话就是 .pcapng是.pcap的升级版 pcap捕获文件格式自计算机网络早期以来一直是通用的包捕获格式。 几乎所有捕获工具都支持pcap格式。 虽然供应商多年来已经创建了新的格式&#xff0c;但大多数工具支持转换为pcap格式。 …

Java之Pcap文件解析(一:Pcap格式分析)

前言 需求 本系列文章主要完成以下功能&#xff1a; 1. 对Pcap文件进行解析&#xff0c;并从中提取TCP和UDP会话 2. 从TCP会话中提取出其数据负载信息 软件最终结果 [主界面] [File 菜单] [Help 的 About 菜单项&#xff0c;版权声明] [选择Pcap文件] [选择输…

wirehark数据分析与取证0051.pcap

什么是wireshark&#xff1f; wiresharekwireshark0051.pcap数据包数据包下载 请私信博主 wiresharek Wireshark&#xff08;前称Ethereal&#xff09;是一个网络封包分析软件。网络封包分析软件的功能是检索取网络封包&#xff0c;并同时显示出最详细的网络封包数据。Wiresha…

C++ 缺少winpcap头文件 pcap.h 解决方案

最近在做课设的时候看到一个代码用到了winpcap的一个头文件 pcap.h &#xff0c;为了能让代码跑起来也是找了很多资料&#xff0c;因此在这里汇总一下。 在官网下载开发包&#xff0c;我下载的是 WinPcap 4.1.2 Developer’s Pack 的版本&#xff0c;下载后解压缩&#xff0c;并…

PACP学习笔记一:使用 PCAP 编程

pcap代码流程 我们首先确定要嗅探哪个接口。在 Linux 中这可能是 eth0&#xff0c;在 BSD 中可能是 xl1&#xff0c;等等。我们可以在字符串中定义这个设备&#xff0c;或者我们可以让 pcap 为我们提供一个接口的名称来完成这项工作。初始化pcap。这其实是实际告诉pcap我们正在…

pcap(cap)包文件解析

https://blog.csdn.net/m0_37710388/article/details/89217421 pcap文件是常用的数据报存储格式&#xff0c;可以理解为就是一种文件格式&#xff0c;只不过里面的数据是按照特定格式存储的&#xff0c;所以我们想要解析里面的数据&#xff0c;也必须按照一定的格式。普通的记事…

pcap1

一、前言 本题方向为Misc——GFSJ0963&#xff0c;难度偏简单 来源地址&#xff1a;攻防世界&#xff08;https://adworld.xctf.org.cn/challenges/list&#xff09; 链接&#xff1a;https://pan.baidu.com/s/1VWT0rDY5P2qvOp_GMCZwkQ 提取码&#xff1a;lyyy 二、解题过程 思…

pcap文件解析

pcap文件解析 1. pcap简介&#xff1a; pcap文件是一种常用的数据报存储文件&#xff0c;这种文件可以保存我们所抓到的报文。它有这固定的存储格式&#xff0c;通过notepad中的插件Hex-Editor我们可以观察其中的16进制数据&#xff0c;从而来进行pcap文件的分析。 2. Pcap文…

pcap详解

一、pcap文件格式 一共三部分&#xff1a; ①Global Header:文件头&#xff08;共24bytes&#xff09;&#xff0c;它定义了本文件的读取规则、最大储存长度限制等内容。 Magic&#xff1a;4Byte&#xff1a;标记文件开始&#xff0c;并用来识别文件自己和字节顺序。0xa1b2c3d…

pcap文件分析

pcap文件解析 pcap文件解析1、 .pcap文件本质2、wireshark查看pcap文件格式文件头数据包头Packet 3、snaplen参数个人理解&#xff1a;tcpdump官网定义&#xff1a;tcpdump源码&#xff1a; pcap文件解析 学了一点.pcap文件的东西&#xff0c;赶紧记录下 1、 .pcap文件本质 …