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

相关文章

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

SpringBoot3.4配置校验新特性的用法详解

《SpringBoot3.4配置校验新特性的用法详解》SpringBoot3.4对配置校验支持进行了全面升级,这篇文章为大家详细介绍了一下它们的具体使用,文中的示例代码讲解详细,感兴趣的小伙伴可以参考... 目录基本用法示例定义配置类配置 application.yml注入使用嵌套对象与集合元素深度校验开发

Python中的Walrus运算符分析示例详解

《Python中的Walrus运算符分析示例详解》Python中的Walrus运算符(:=)是Python3.8引入的一个新特性,允许在表达式中同时赋值和返回值,它的核心作用是减少重复计算,提升代码简... 目录1. 在循环中避免重复计算2. 在条件判断中同时赋值变量3. 在列表推导式或字典推导式中简化逻辑

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll