Java中八大包装类举例详解(通俗易懂)

2025-02-16 05:50

本文主要是介绍Java中八大包装类举例详解(通俗易懂),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Java中八大包装类举例详解(通俗易懂)》:本文主要介绍Java中的包装类,包括它们的作用、特点、用途以及如何进行装箱和拆箱,包装类还提供了许多实用方法,如转换、获取基本类型值、比较和类型检测,...

一、包装类(Wrapper Class)

1、简要介绍

Java 中的包装类是用于将基本数据类型(如 int、char、boolean 等)包装成对象的类。每种基本数据类型都有对应的包装类,这些包装类提供了一种面向对象的方式来处理基本数据类型,允许它们被用于需要对象的场景,如集合框架、泛型等。

以下是 Java 中基本数据类型及其对应的包装类:

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

2、包装类特点

  • 封装性:所有的包装类都是 final 类,这意味着它们不能被继承。这种设计确保了包装类的行为和特性的一致性,从而避免了子类可能引入的不确定性。

  • 不可变性:包装类的实例一旦被创建后,其中保存的基本数据类型数据就不能再被改变。这种不可变性使得包装类在多线程环境中更加安全,避免了因数据被意外修改而导致的错误。

  • 提供方法:包装类封装了许多实用的方法,提供了丰富的功能。例如,它们支持数据类型转换、判断字符串的大小写、以及获取最大值和最小值等。

  • 继承关系:除了 Characphpter 和 Boolean 之外,其他所有的包装类都继承自 Number 类。这种继承关系使得这些包装类能够共享一些通用的功能和特性,例如数字的比较和转换,这为在不同数值类型之间的操作提供了一致的接口。

    Java中八大包装类举例详解(通俗易懂)

3、包装类用途

  • 对象操作:在Java中,许多集合类和框架方法需要对象作为参数,而不是基本数据类型。为了满足这一需求,包装类提供了将基本数据类型转换为对象的机制。通过使用包装类,我们可以轻松地在这些方法中传递基本数据类型。

  • Null值处理:基本数据类型无法为null,而包装类则可以。这一特性在某些情况下非常有用,例如在方法参数中,需要表示可选值或缺省值时。通过使用包装类,我们能够更灵活地处理这些场景,确保代码的健壮性和可读性。这种设计使得我们在处理数据时,可以更方便地进行null值检查,并在需要时安全地进行区分,从而提高了代码的灵活性。

二、装箱和拆箱

1、装箱和拆箱

装箱(Boxing)是将基本数据类型转换为相应的包装类的过程。拆箱(Unboxing)是将包装类转换为基本数据类型的过程。

手动装箱就是使用一个值创建一个 Integer 对象:

int num = 50000;
Integer boxedInt1 = new Integer(num); // 手动装箱方式一
Integer boxedInt2 = Integer.valueOf(num); // 手动装箱方式二

手动拆箱就是使用 Integer 类型对象的 intValue() 方法来获取这个对象的 int 值:

Integer boxedInt = new Integer(5);
int num = boxedInt.intValue(); // 手动拆箱

2、自动装箱和自动拆箱

Java 5引入了自动装箱(Auto-boxing)和自动拆箱(Auto-unboxing)机制,简化了基本数据类型与包装类之间的转换过程。

自动装箱是将基本数据类型自动转换为其对应的包装类对象的过程。

int num = 50000;
Integer boxedInt = num; // 自动装箱

自动拆箱则是将包装类对象自动转换为其对应的基本数据类型。

Integer boxedInt = new Integer(50000);
int num = boxedInt; // 自动拆箱

3、自动装箱和自动拆箱的底层实现

1)自动装箱的底层实现

自动装箱是通过调用包装类的valueOf()方法来实现的。

我们可以通过调试来验证这一结论,在要发生自动装箱的地方打上断点,然后直接跳到这个断点处,然后强制进入(force step into),就会进入到 valueOf() 方法中。

2)自动拆箱的底层实现

自动拆箱是通过调用包装类对象的xxxValue()方法来实现的。

我们可以通过调试来验证这一结论,在要发生自动拆箱的地方打上断点,然后直接跳到这个断点处,然后强制进入(force step into),就会进入到 xxxValue() 方法中。

三、包装类的缓存机制

1、简要介绍

Java中的包装类缓存机制是为了优化性能和节省内存而设计的。

它为整型(Byte、Short、Integer、Long)、字符型(Character)和布尔型(Boolean)的包装类提供了缓存,确保在这些类型的小范围值之间可以复用对象。而对于浮点数类型的包装类(Float、Double),则没有这种缓存机制,意味着每次都需要创建新的对象。

这样一来,Java在处理常用值时更加高效,但在浮点数处理上则相对简单直接。

2、缓存范围

对于 Integer 类,Java会缓存范围在 -128 到 127 之间的所有整数。

对于 Byte、Short 和 Character 类,缓存的范围也是类似的。具体范围如下:

  • Byte:-128 到 127
  • Short:-128 到 127
  • Character:0 到 127(即所有的ASCII字符)
  • Boolean:只有 true 和 false 两个值会被缓存。

3、触发缓存机制

只有调用 valueOf() 方法时,如果要创建的值已经被缓存,则会触发缓存机制。

我们可以查看 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);
    }

如果要创建的 Integer 对php象的值在预定范围内,则返回缓存的对象,如果不在范围内,则直接新创建一个对象。

4、测试缓存机制

我们可以通过使用 valueOf() 方法创建两个值一样且值在范围内的对象,然后比较它们的引用是否相等,如果相等,则能证明缓存机制的存在。

public class Example {
	pubhttp://www.chinasem.cnlic static void main(String[] args) {
		Integer i1 = Integer.valueOf(1);
		Integer i2 = Integer.valueOf(1);

		System.out.println(i1 == i2);
	}
}

运行结果:

Java中八大包装类举例详解(通俗易懂)

这样就能证明缓存机制的存在。

四、包装类的方法

1、基本转换方法

parseInt(String s), parseDouble(String s), parseBoolean(String s) 等:将字符串转换为相应的基本类型。

valueOf(String s): 返回对应类型的包装类实例,例如 Integer.valueOf("123") 返回一个 Integer 对象。

2、获取基本类型值

intValue(), doubleValue(), charValue(), booleanValue() 等: 返回包装类中封装的基本类型值。

示例:

Integer num = new Integer(5);
int value = num.intValue();

3、常量字段

MAX_VALUE, MIN_VALUE: 返回该包装类所表示的基本类型的最大值和最小值。

例如:

Integer.MAX_VALUE 返回 2147483647,

Double.MIN_VALUE 返回 4.9E-324。

4、比较方法

compareTo(T another): 用于比较两个包装类对象的大小。

equals(Object obj): 判断两个对象是否相等。

示例:

Integer.compare(x, y) 方法比较两个 Integer 对象的值。

5、类型检测

isNaN(), isInfinite(): 用于 Double 和 Float 以检测是否为非数字或无穷大。

isLetter(char ch):检查指定的字符是否为字母(包括大写和小写字母)。

char c = 'A';
boolean isLetter = Character.isLetter(c); // 返回 true

isDigit(char ch)检查指定的字符是否为数字。

char c = '5';
boolean isDigit = Character.isDigit(c); // 返回 true

isWhitespace(char ch):检查指定的字符是否为白空格字符(如空格、制表符等)。

char c = ' ';
boolean isWhitespace = Character.isWhitespace(c); // 返回 true

五、补充

1、精度提升

public class Example {
	public static void main(String[] args) {
		Object obj = true ? new Integer(1) : new Double(2.0);
		System.out.println(obj);
	}
}

输出结果是:

Java中八大包装类举例详解(通俗易懂)

这是因为由于 Double 精度高,而且这里使用的是三元运算符,所以 Integer 会被提升精度为 Double,所以最终输出的是一个浮点数。

实际上的具体操作应该是:

创建一个 Integer 对象,然后这个对象自动拆箱得到一个 int 类型的值,然后由于后面是 Double 类型,这个 int 类型的值提升为 double 类型的值,然后通过自动装箱得到一个 Double 类型的对象。

我们也可以通过 instanceof 操作符测试一下:

public class Example {
	public static void main(String[] args) {
		Object obj = true ? new Integer(1) : new Double(2http://www.chinasem.cn.0);
		System.out.println(obj instanceof Double);
	}
}

输出结果:

Java中八大包装类举例详解(通俗易懂)

所以说这里的 obj 指向的对象确实是一个 Double 类的对象。

2、包装类与字符串相互转换

1)包装类转换为字符串

		Integer i = 10000;
		
		// 方式一
		String str1 = i + "";
		
		// 方式二
		String str2 = i.toString();
		
		// 方式三
		String str3 = String.valueOf(i);

这里对于方法三,实际上内部也是调用 toString() 方法的。

2)字符串转换为包装类

		String str = "10000";

		// 方式一
		Integer i1 = Integer.parseInt(str);

		// 方式二
		Integer i2 = Integer.valueOf(str);
		
		// 方式三
		Integer i3 = new Integer(str);

这里看似通过字符串创建 Integer 类对象有三种方法,实际上就一种方法,对于方法二和方法三内部实际上都是调用js parseInt() 方法来将字符串转换为整型的。

3、缓存机制

上面提到的缓存机制只可能在调用 valueOf() 方法时触发,所以对于直接调用构造方法则不会触发缓存机制。

我们知道自动装箱底层调用的也是 valueOf() 方法,所以说自动装箱也可以触发缓存机制。

我们还知道缓存机制是有范围的,超出范围的值创建的对象都是新创建的。

所以我们就能很自然的得到以下代码的运行结果:

public class Example {
	public static void main(String[] args) {
		Integer i1 = new Integer(1);
		Integer i2 = new Integer(1);

		System.out.println(i1 == i2); // false

		Integer i3 = 1;
		Integer i4 = 1;

		System.out.println(i3 == i4); // true

		Integer i5 = 128;
		Integer i6 = 128;

		System.out.println(i5 == i6); // false
	}
}

运行结果:

Java中八大包装类举例详解(通俗易懂)

4、判断值是否相等

只要判断中有基本数据类型,则判断的就是值是否相等,也就是说包装类在这时会自动拆箱。

public class Example {
	public static void main(String[] args) {
		Integer i1 = 128;
		int i2 = 128;

		System.out.println(i1 == i2);
	}
}

运行结果:

Java中八大包装类举例详解(通俗易懂)

总结 

到此这篇关于Java中八大包装类的文章就介绍到这了,更多相关Java八大包装类内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于Java中八大包装类举例详解(通俗易懂)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153458

相关文章

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Java操作Word文档的全面指南

《Java操作Word文档的全面指南》在Java开发中,操作Word文档是常见的业务需求,广泛应用于合同生成、报表输出、通知发布、法律文书生成、病历模板填写等场景,本文将全面介绍Java操作Word文... 目录简介段落页头与页脚页码表格图片批注文本框目录图表简介Word编程最重要的类是org.apach

C#读写文本文件的多种方式详解

《C#读写文本文件的多种方式详解》这篇文章主要为大家详细介绍了C#中各种常用的文件读写方式,包括文本文件,二进制文件、CSV文件、JSON文件等,有需要的小伙伴可以参考一下... 目录一、文本文件读写1. 使用 File 类的静态方法2. 使用 StreamReader 和 StreamWriter二、二进

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

SpringBoot+Docker+Graylog 如何让错误自动报警

《SpringBoot+Docker+Graylog如何让错误自动报警》SpringBoot默认使用SLF4J与Logback,支持多日志级别和配置方式,可输出到控制台、文件及远程服务器,集成ELK... 目录01 Spring Boot 默认日志框架解析02 Spring Boot 日志级别详解03 Sp

java中反射Reflection的4个作用详解

《java中反射Reflection的4个作用详解》反射Reflection是Java等编程语言中的一个重要特性,它允许程序在运行时进行自我检查和对内部成员(如字段、方法、类等)的操作,本文将详细介绍... 目录作用1、在运行时判断任意一个对象所属的类作用2、在运行时构造任意一个类的对象作用3、在运行时判断

java如何解压zip压缩包

《java如何解压zip压缩包》:本文主要介绍java如何解压zip压缩包问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java解压zip压缩包实例代码结果如下总结java解压zip压缩包坐在旁边的小伙伴问我怎么用 java 将服务器上的压缩文件解压出来,

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

SpringBoot中SM2公钥加密、私钥解密的实现示例详解

《SpringBoot中SM2公钥加密、私钥解密的实现示例详解》本文介绍了如何在SpringBoot项目中实现SM2公钥加密和私钥解密的功能,通过使用Hutool库和BouncyCastle依赖,简化... 目录一、前言1、加密信息(示例)2、加密结果(示例)二、实现代码1、yml文件配置2、创建SM2工具