从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 新闻合订本
    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 新闻合订本
    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

    • 我的 Java 学习路线
    • 安装 Java
    • Java 数据类型

    • Java 多版本配置
    • 面向对象

    • Java 核心类

      • 基本包装类型
        • 什么是基本包装类型
        • 包装类型的常用方法和属性
        • 🌟 基本类型和包装类型之间的自动转换
        • 缓存的踩坑
        • equals 的踩坑
        • 小结
        • 参考
      • BigInteger 类
      • BigDecimal 类
      • 深入 BigDecimal
    • IO

    • Java 与时间

    • 异常处理

    • 哈希和加密算法

    • Java8 新特性

    • 网络编程

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • JavaSE
  • Java 核心类
2022-12-16
目录

基本包装类型

# 基本包装类型

介绍下 Java 的包装类型。

# 什么是基本包装类型

处理对象需要额外的开销(例如申请内存,分配内存等),因此基本数据类型是不作为对象使用的(提高性能)。

但是,Java 的很多方法都需要将对象作为参数,因此,Java 提供了包装类型。例如,将 int 包装成 Integer 类,double 包装成 Double 类。

Java 为基本数据类型提供了 Byte、Short、Integer、Long 、Float、 Double、Boolean、Character 等包装类,这些包装类都在 java.lang 包里,因此可以直接使用,不用 import。

大部分包装类的名称和基本数据类型的名称一样,但首字母大写(Integer 和 Character 除外)

# 包装类型的常用方法和属性

大部分包装类之间的方法都很类似,主要分为以下几类

  • 构造方法
  • valueOf(): 包装类的静态方法,用于创建一个包装对象
  • 一组将包装类转换成基本数据类型的方法,方法名类似于 dataTypeValue()
  • 一组类似 pareDataType() 的方法,用来转换为基本数据类型(可以添加参数 radix,标明转换的基数)
  • compareTo() 比较大小

例如,Integer 的类图如下(其他包装类也类似)。我们依次来介绍并实践各个方法

# 构造方法

可以用基本数据类型值,也可以字符串来构造包装类。例如,newDouble(5.0)、new Double("5.0")、new Integer(5)和 new Integer("5")。

包装类没有无参构造方法。所有包装类的实例都是不可变的,这意味着一旦创建对象后,它们的内部值就不能再改变。

示例代码如下:

// 演示包装类的构造方法

public class WrapperClassDemo{
  public static void main(String[] args) {
    byte b = 1;
    Byte byte1 = new Byte(b);
    Byte byte2 = new Byte("112");
    System.out.println("Byte: " + byte1 + ' ' + byte2);

    short s = 1;
    Short short1 = new Short(s);
    Short short2 = new Short("112");
    System.out.println("Short:"  + short1 + ' ' + short2);

    Integer int1 = new Integer(111);
    Integer int2 = new Integer("112");
    System.out.println("Integer:"  + int1 + ' ' + int2);

    Long long1 = new Long(111L);
    Long long2 = new Long("112");
    System.out.println("Long:"  + long1 + ' ' + long2);

    Float float1 = new Float(11.1f);
    Float float2 = new Float("11.2");
    System.out.println("Float:"  + float1 + ' ' + float2);

    Double double1 = new Double(11.1);
    Double double2 = new Double("111.22");
    System.out.println("Double:"  + double1 + ' ' + double2);


    char c = 'A';
    Character char1 = new Character(c);
    Character char2 = new Character('A');
    System.out.println("Character:"  + char1 + ' ' + char2);

    Boolean boolean1 = new Boolean("true");
    Boolean boolean2 = new Boolean("True");
    Boolean boolean3 = new Boolean(true);
    System.out.println("Boolean:"  + boolean1 + ' ' + boolean2 + ' ' + boolean3);
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# valueOf()

包装类有一个有用的静态方法,vauleOf(),其参数可以是基本数据类型 和 字符串,该方法创建一个新对象,并将其初始化为参数所表示的值。

演示如下:代码和上一小节类似。

public class WrapperClassDemo2 {
  public static void main(String[] args) {
    byte b = 1;
    Byte byte1 = Byte.valueOf(b);
    Byte byte2 = Byte.valueOf("112");
    System.out.println("Byte: " + byte1 + ' ' + byte2);

    short s = 1;
    Short short1 = Short.valueOf(s);
    Short short2 = Short.valueOf("112");
    System.out.println("Short:"  + short1 + ' ' + short2);

    Integer int1 = Integer.valueOf(111);
    Integer int2 = Integer.valueOf("112");
    System.out.println("Integer:"  + int1 + ' ' + int2);

    Long long1 = Long.valueOf(111L);
    Long long2 = Long.valueOf("112");
    System.out.println("Long:"  + long1 + ' ' + long2);

    Float float1 = Float.valueOf(11.1f);
    Float float2 = Float.valueOf("11.2");
    System.out.println("Float:"  + float1 + ' ' + float2);

    Double double1 = Double.valueOf(11.1);
    Double double2 = Double.valueOf("111.22");
    System.out.println("Double:"  + double1 + ' ' + double2);


    char c = 'A';
    Character char1 = Character.valueOf(c);
    Character char2 = Character.valueOf('A');
    System.out.println("Character:"  + char1 + ' ' + char2);

    Boolean boolean1 = Boolean.valueOf("true");
    Boolean boolean2 = Boolean.valueOf("True");
    Boolean boolean3 = Boolean.valueOf(true);
    System.out.println("Boolean:"  + boolean1 + ' ' + boolean2 + ' ' + boolean3);


  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# dataTypeValue()

大部分包装类都有一组类似 dataTypeValue() 的方法:

  • byteValue()
  • shortValue()
  • intValue()
  • longValue()
  • floatValue()
  • doubleValue()
  • booleanValue()
  • charValue()

这些方法返回包装类 包装的基本数据类型。注意:返回数制类型的 dataTypeValue() 只有数值类的包装类才有。返回 booleanValue() 的只有 Boolen 包装类才有,charValue() 同理。

//演示 dataTypeValue方法
public class WrapperClassDemo3 {
  public static void main(String[] args) {
    Integer integer = new Integer(111);
    byte b1 = integer.byteValue();
    short s1 = integer.shortValue();
    int i1 = integer.intValue();
    long l1 = integer.longValue();
    float f1 = integer.floatValue();
    double d1 = integer.doubleValue();

    System.out.println("b1: " + b1);
    System.out.println("s1: " + s1);
    System.out.println("i1: " + i1);
    System.out.println("l1: " + l1);
    System.out.println("f1: " + f1);
    System.out.println("d1: " + d1);

    Boolean b = new Boolean(true);
    boolean boolean1 =  b.booleanValue();
    System.out.println("boolean1: " + boolean1);

    Character c = new Character('a');
    char c1 = c.charValue();
    System.out.println("c1: " + c1);
  

  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# pareDataType()

大部分包装类都有一组类似 pareDataType() 的方法:

  • Integer.pareInt(String s):将一个数值字符串转为 int 值
  • Double.parseDouble(String s):将一个数值字符串转为 double 值

默认情况下,Java 是将数值字符串当成 10 进制下的值,但有个重载的方法 Integer.pareInt(String s, int radix),可以说明数值字符串的基数,例如说明该数是 2 进制下的:

public class WrapperClassDemo6 {
  public static void main(String[] args) {
    System.out.println(Integer.parseInt("11"));
    System.out.println(Integer.parseInt("11",2)); //将二进制数11转为十进制数,输出3
    System.out.println(Integer.parseInt("11",8)); //将八进制数11转为十进制数,输出9
    System.out.println(Integer.parseInt("11",16));//将16进制数11转为十进制数,输出17
  }
}
1
2
3
4
5
6
7
8

注意,要转换的数值字符串得是合法的,例如将 Integer.parseInt("12",2) 会发生错误。因为二进制数里没有 2.

如果要反过来,将一个十进制数转为其他进制,可以用 String 的 format 方法

String.format("%x", 26)); //将26转为十六进制,也就是1a
1

更多参数说明:

转换 参数类别 说明
'b','B' 常规 如果参数 arg 为 null,则结果为 "false"。如果 arg 是一个 boolean 值或 Boolean,则结果为 String.valueOf()返回的字符串。否则结果为 "true"。
'h','H' 常规 如果参数 arg 为 null,则结果为 "null"。否则,结果为调用 Integer.toHexString(arg.hashCode())得到的结果。
's','S' 常规 如果参数 arg 为 null,则结果为 "null"。如果 arg 实现 Formattable,则调用 arg.formatTo。否则,结果为调用 arg.toString()得到的结果。
'c','C' 字符 结果是一个 Unicode 字符
'd' 整数 结果被格式化为十进制整数
'o' 整数 结果被格式化为八进制整数
'x','X' 整数 结果被格式化为十六进制整数
'e','E' 浮点 结果被格式化为用计算机科学记数法表示的十进制数
'f' 浮点 结果被格式化为十进制数
'g','G' 浮点 根据精度和舍入运算后的值,使用计算机科学记数形式或十进制格式对结果进行格式化。
'a','A' 浮点 结果被格式化为带有效位数和指数的十六进制浮点数
't','T' 日期/时间 日期和时间转换字符的前缀。请参阅日期/时间转换。
'%' 百分比 结果为字面值'%'('\u0025')
'n' 行分隔符 结果为特定于平台的行分隔符

# compareTo()

String 类的 compareTo() 方法用来比较两个字符串,包装类中 compareTo() 则用于比较两个数值,大于时返回 1,等于时返回 0,小于是返回-1。

public class WrapperClassDemo5 {
  public static void main(String[] args) {
    int b1 = new Double(12.4).compareTo(new Double(12.3));
    int b2 = new Double(12.3).compareTo(new Double(12.3));
    int b3 = new Double(12.3).compareTo(new Double(12.4));

    System.out.println("b1: " + b1);
    System.out.println("b2: " + b2);
    System.out.println("b3: " + b3);
  }
}
1
2
3
4
5
6
7
8
9
10
11
b1: 1
b2: 0 
b3: -1
1
2
3

# MAX_VALUE 和 MIN_VALUE

每一个数值包装类都有常量 MAX_VALUE 和 MIN_VALUE。

  • 对于 Byte 、 Short、Integer 和 Long 而言,MIN_VALUE 表示对应的基本类型 byte、short、int 和 long 的最小值。
  • 对 Float 和 Double 类而言,MIN_VALUE 表示 float 型 和 double 型的最小正值。

演示如下:

public class WrapperClassDemo4 {
  public static void main(String[] args) {

    System.out.println("Byte.MAX_VALUE: " + Byte.MAX_VALUE);
    System.out.println("Byte.MIN_VALUE: " + Byte.MIN_VALUE);

    System.out.println("Integer.MAX_VALUE: " + Integer.MAX_VALUE);
    System.out.println("Integer.MIN_VALUE: " + Integer.MIN_VALUE);

    System.out.println("Float.MIN_VALUE: " + Float.MIN_VALUE);
    System.out.println("Float.MAX_VALUE: " + Float.MAX_VALUE);

    System.out.println("Double.MIN_VALUE: " + Double.MIN_VALUE);
    System.out.println("Double.MAX_VALUE: " + Double.MAX_VALUE);
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

输出如下:

Byte.MAX_VALUE: 127
Byte.MIN_VALUE: -128
Integer.MAX_VALUE: 2147483647
Integer.MIN_VALUE: -2147483648
Float.MIN_VALUE: 1.4E-45
Float.MAX_VALUE: 3.4028235E38
Double.MIN_VALUE: 4.9E-324
Double.MAX_VALUE: 1.7976931348623157E308
1
2
3
4
5
6
7
8

# 🌟 基本类型和包装类型之间的自动转换

根据代码的上下文,基本数据类型值可以使用自动转换成一个对象(这个过程称为装箱,boxing),反过来一个包装类也可以自动转换成基本数据类型(这个过程称为开箱, unboxing )。

Java 允许基本类型和包装类类型之间进行自动转换:

  • 如果一个基本类型值出现在需要对象的环境中,编译器会将基本类型值进行自动装箱;
  • 如果一个对象出现在需要基本类型值的环境中,编译器会将对象进行自动开箱。

这称为自动装箱和自动开箱。

例如,以下语句是等价的:

Integer intObject = new Integer(5);
Integer intObject2 = 5;
1
2

在计算和创建对象的时候,也会在 i 动装箱和拆箱

    Integer[] intArray = {1,2,3};
    System.out.println(intArray[0] + intArray[1] + intArray[2]);
1
2

第一行中,基本数据类型 1,2,3 会被自动装箱为对象 Integer(1), Integer(2), Integer(3)。

第二行中,对象 intArray[0],ntArray[1],ntArray[2] 会被自动转换成 int 值,然后相加

# 缓存的踩坑

观察以下代码,推理下应该输出什么?

public class BigIntegerDemo3 {
  public static void main(String[] args) {
    Integer a = 1000, b = 1000;
    System.out.println("a==b? : " + (a == b));

    Integer c = 100, d = 100;
    System.out.println("a==b? : " + (c == d));
  }
}

1
2
3
4
5
6
7
8
9
10

答案是

a==b? : false
a==b? : true
1
2

我们知道,当两个对象用 == 比较的时候,会比较是否同一个引用。如果不是同一个,会返回 false。那为什么第二个返回 true 呢?

其实,当我们这样声明对象的时候 Integer c = 100,会调用 public static Integer valueOf(int i) 进行自动装箱,类似这样:

Integer c = Integer.valueOf(100);
1

我们可以看看 valueOf 方法的代码:(在 Integer.java 的第 829 行)

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

如果值的范围在-128 到 127 之间,它就从数组 cache 里缓存返回一个实例,否则返回一个新对象。

我们继续看 IntegerCache 是什么:是一个内部私有类 IntegerCache,其内部缓存了从 -128 ~ 127 的所有整数对象。

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
	//省略部分代码
	for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
	//省略部分代码
}
1
2
3
4
5
6
7
8
9

所以,Integer c = 100, d = 100; 这句代码中,两者指向的是同一个对象,因此用 == 判断得到的是 true。

为什么会使用缓存数组?因为小整数使用的频率较高,使用缓存能提高效率,减少内存占用,提高性能(就好比 CPU 就有高速缓存)

除了 Integer 类之外,其他的包装类也存在类似的设计(Byte,short,Long 等),感兴趣的读者请自行看源码。

知道这个特性,对日常开发有什么影响吗?比较两个数是否相等在计算机里是很常用的,并且后面我们会讲到反射,知道这个细节,可以让你不误用。

另外要注意的是,new 的 Integer 对象不适用缓存数组

Integer d1 = new Integer(1);
Integer d2 = new Integer(1);
System.out.println(d1 == d2); //false
1
2
3

# equals 的踩坑

以 Integer 为例,Integer.equals 方法源码如下:

public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}
1
2
3
4
5
6

先判断参数 obj 是否是 Integer 类型,如果不是,则直接返回 false。如果是 Integer 类型,再进一步判断 int 值是否相等。也就是说,如果调用了 Integer 的 equals 方法,必须要求入参也是 Integer 类型,否则该方法会直接返回 false。演示如下:

    long long1 = 1000L;
    Integer integer = 1000;
    System.out.println( long1 == integer);  //true
    System.out.println( integer.equals(long1)); //flase
1
2
3
4

即使调用 Objects.equals() 也是一样的,因为其内部也还是调用对象的 equals 方法。

# 小结

本文讲了如下内容:

  • 什么是包装类
  • 包装类的常用方法
  • 包装类的常用属性
  • 包装类的自动装箱和拆箱
  • 数值包装类的缓存数组
  • 数值包装类的 equals 的坑

# 参考

《Java 语言程序设计-基础篇》第 10.7 节

Integer 缓存 IntegerCache 详解_谷哥的小弟的博客-CSDN 博客 (opens new window)

为什么 Java 中“1000=1000”为 false,而”100==100“为 true? (opens new window)

Why 1000 == 1000 Returns False, but 100 == 100 Returns True in Java? - DZone (opens new window)

上次更新: 2025/6/3 09:31:54
内部类
BigInteger 类

← 内部类 BigInteger 类→

最近更新
01
新闻合订本 2025-10
10-31
02
2025 年 10 月记
10-30
03
用 AI 批量优化思源笔记排版
10-15
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式