前言:
包装类就像是给基本数据类型穿上了一层“外衣”,让它们在Java的世界里变得更加灵活和强大。
- 对象化的数据:在Java中,一切皆为对象(面向对象程序设计)。虽然基本数据类型(比如int, double)不是对象,但有时候我们需要像对待对象一样来使用它们。包装类(如Integer, Double)就提供了这样的功能,让基本数据类型也能拥有对象的身份,这样我们可以利用面向对象编程的各种特性。
- 玩转集合工具:Java中的集合(例如ArrayList、HashSet等)只能存放对象,不能直接存储基本数据类型。有了包装类,我们就可以轻松地把基本数据类型转换成对象,然后存入集合中,就像把小玩具放进大盒子里一样简单。
- 参数传递更自由:有时候,方法需要接收对象作为参数,而不仅仅是基本数据类型。这时候,包装类就能派上用场了,它允许我们将基本数据类型转换为对象,使得方法调用更加灵活。
- 自动转换,代码更简洁:从Java 5开始,语言引入了自动装箱和拆箱的功能,这意味着基本数据类型和对应的包装类之间可以自动相互转换。这不仅简化了代码编写,还减少了出错的机会。
- 处理空值:包装类能够表示“无值”的状态(即null),这是基本数据类型做不到的。在实际开发中,比如查询数据库时,我们可能遇到没有结果的情况,这时null就显得尤为重要,因为它能明确告诉我们“这里什么都没有”。
那么就由小编带着大家彻底搞清楚包装类是什么?具体如何使用,对于新手而言,做到什么程度就足够了!!
开始之前,大家可不可以给小编一个免费的赞或者关注(我们一起进步啊!!!!)
这次我们对于代码的解释更加详细了!!!
概述:
什么是包装类?
官方定义:
- 在Java编程语言中,包装类(Wrapper Class)是将基本数据类型封装成对象的类。
- 每个基本数据类型都有一个对应的包装类,它们位于java.lang包中。
- 这些类提供了多种方法来操作其对应的基本数据类型,包括转换、解析和格式化等。
- 包装类还支持将基本数据类型转换为字符串以及从字符串转换回基本数据类型的功能。
- 此外,包装类能够表示“null”值,这是基本数据类型所不具备的能力。
大白话拆解:
圣诞节你要送给女朋友一个小小的礼物!!!(主播主播别骂了,没女朋友怎么办?...送给自己),比如一颗糖。这颗糖就是我们说的基本数据类型,比如数字5或者字符'A'。但是有时候,我们需要把这颗糖装进一个漂亮的盒子里,这个盒子就像是包装类。为什么需要这样做呢?
- 为了方便携带:有些人只接受装在盒子里的礼物(比如Java的集合工具),所以我们就需要把糖放进盒子里再带过去。
- 可以写上名字:盒子上面可以写上信息,比如是谁送的,什么时候送的。同样地,包装类可以做更多事情,比如告诉计算机这个数字是从哪里来的,或者它代表什么意思(可以表述很多其他信息,不仅仅是美观,还有内容,懂我意思吧就是小情书,嘻嘻)。
- 空盒子的概念:有时候,我们可能没有糖,但还是想给别人一个盒子,表示“我本来想给你糖的,但现在没有”。(就是说给你女朋友画大饼,虽然说我现在啥也没,但是我保证以后啥都有)这就是包装类中的
null
,它告诉我们“这里什么都没有”,而不仅仅是0或者空。
包装类就像是给基本数据类型穿上了一件特别的衣服,让它们在某些情况下更加有用和灵活。
当你学习Java的时候,了解包装类是非常重要的,因为它们会帮助你更好地使用Java的各种功能。
为什么需要包装类:
官方语言表述:
- 使用集合类:Java中的集合类(如ArrayList, HashMap等)只能存储对象,而不能直接存储基本数据类型。所以,如果你想在ArrayList中存储一些整数,你就需要用Integer包装类来包装你的int值,这样就可以把它们当作对象存入ArrayList中了。
- 泛型的支持:泛型是Java的一种特性,它允许你编写可以处理多种数据类型的代码。但是,泛型只能用于对象,不能用于基本数据类型。因此,如果你想要利用泛型的优势,你需要使用包装类。
- 方法参数和返回值:有些方法可能要求传入的对象作为参数,或者返回一个对象。在这种情况下,如果我们要传递或返回一个基本数据类型的值,我们就需要使用相应的包装类来满足方法的要求。
- 空值表示:基本数据类型总是有一个默认值(例如,int的默认值是0),但是有时候我们希望表达“没有值”的概念。包装类允许我们这样做,因为它们可以被赋予null值,表示不存在的值。
- 可读性和功能增强:包装类提供了一些有用的方法,可以帮助我们更方便地操作基本数据类型。例如,你可以使用Integer.parseInt()将字符串转换为整数,或者使用Double.valueOf()将字符串转换为双精度浮点数。
大白话拆解:
- 你在玩一个游戏,这个游戏里有两种类型的物品:
- 一种是直接可以用的简单物品(比如金币、药水),另一种是装在箱子里的高级物品(比如宝剑、魔法书)。
- 简单物品可以直接使用,而高级物品需要先打开箱子才能用。
- 在Java中,基本数据类型就像是那些可以直接使用的简单物品,而包装类就像是装有高级物品的箱子。
细致拆分:
1. 为了和对象一起玩耍
Java是一个面向对象的语言,它喜欢所有东西都是对象。但是,基本数据类型不是对象,它们是“裸露”的数据。当我们要使用一些只接受对象的工具或功能时,比如集合(Collection)或者泛型(Generics),我们就需要把基本数据类型“装进盒子”——也就是使用包装类。这样,它们就可以和其他对象一起愉快地玩耍了。
举个栗子:
集合框架:假设你想创建一个ArrayList来存储一系列的整数。ArrayList只能存储对象,不能直接存储基本数据类型int。所以你需要用Integer来代替int,就像把每个整数都放进一个小盒子里再存进去。
List<Integer> numbers = new ArrayList<>();
numbers.add(5); // 这里的5会被自动装箱成Integer对象
2. 处理空值的情况
有时候,我们可能没有具体的数值,但还是想表示“这里什么都没有”。对于基本数据类型,这是不可能的,因为它们总是有一个默认值(比如int的默认值是0)。但是包装类可以表示null,这相当于说“这个位置现在是空的”。
举个栗子:
数据库查询:当你从数据库中获取一条记录时,某些字段可能为空。如果你用基本数据类型来存储这些字段,你将无法区分“0”和“没有值”。但是使用包装类,你可以通过null来明确表示“这个字段没有值”。
Integer age = resultSet.getInt("age");
if (resultSet.wasNull()) {
age = null; // 表示数据库中的年龄字段为空
}
3. 方法参数和返回值
有些方法设计为接收或返回对象,而不是基本数据类型。在这种情况下,我们需要使用包装类来传递或接收这些值。
举个栗子:
API调用:假设你正在使用一个API,它要求你传入一个Double对象作为参数,而不是double基本类型。这时候你就需要用Double来包装你的数值。
public void setTemperature(Double temp) {
// 方法内部逻辑
}
Double temperature = 25.5;
setTemperature(temperature); // 传递Double对象
4. 自动装箱与拆箱(后面会讲到)
从Java 5开始,语言引入了自动装箱(Autoboxing)和拆箱(Unboxing)机制,这意味着你可以在基本数据类型和包装类之间自由转换,而不必每次都显式地进行转换。这使得代码更加简洁和易读。
举个栗子:
简化代码:你不再需要每次手动创建包装类实例,Java会自动为你处理
List<Integer> numbers = new ArrayList<>();
numbers.add(10); // 自动装箱:10被转换为Integer对象
int sum = numbers.get(0) + 5; // 自动拆箱:Integer对象被转换为int
有哪些包装类
概述:
Java 针对八种基本数据类型定义了相应的引用类型:包装类(封装类)。有了 类的特点,就可以调用类中的方法,Java才是真正的面向对象。
Java为每一种基本数据类型都定义了一个对应的包装类(Wrapper Class),这些包装类位于java.lang包中。以下是八种基本数据类型及其对应的包装类:
- byte - Byte
- 用于表示8位有符号整数。
- short - Short
- 用于表示16位有符号整数。
- int - Integer
- 用于表示32位有符号整数,是最常用的一种整数类型。
- long - Long
- 用于表示64位有符号整数,适用于需要更大范围整数值的场景。
- float - Float
- 用于表示32位单精度浮点数。
- double - Double
- 用于表示64位双精度浮点数,提供了更高的精度和更大的数值范围。
- char - Character
- 用于表示16位Unicode字符。
- boolean - Boolean
- 用于表示布尔值,即true或false。
包装类的特点和用途:
包装类不仅提供了将基本数据类型转换为对象的能力,还包含了许多有用的静态方法和常量,使得操作这些数据更加方便。例如:
Integer.parseInt(String s):将字符串转换为整数。
Double.valueOf(String s):将字符串转换为Double对象。
Character.isLetter(char c):检查字符是否为字母。
Boolean.getBoolean(String name):从系统属性中获取布尔值。
举个栗子:
有一个场景:我们需要从用户那里获取一些信息,包括年龄(整数)、身高(浮点数)、名字首字母(字符)和是否同意条款(布尔值)。然后,我们将对这些信息进行一些处理。
import java.util.Scanner;
public class WrapperClassExample {
public static void main(String[] args) {
// 创建一个Scanner对象,用于从控制台读取用户的输入
Scanner scanner = new Scanner(System.in);
// 1. 获取并转换年龄
System.out.print("请输入您的年龄: ");
String ageString = scanner.nextLine(); // 用户输入的是字符串形式
int age = Integer.parseInt(ageString); // 使用Integer包装类将字符串转换为整数
// 2. 获取并转换身高
System.out.print("请输入您的身高(米): ");
String heightString = scanner.nextLine(); // 用户输入的是字符串形式
double height = Double.valueOf(heightString); // 使用Double包装类将字符串转换为双精度浮点数
// 3. 获取并检查名字首字母
System.out.print("请输入您名字的首字母: ");
char initial = scanner.nextLine().charAt(0); // 获取第一个字符
if (Character.isLetter(initial)) { // 使用Character包装类检查字符是否为字母
System.out.println("您的名字首字母是字母: " + initial);
} else {
System.out.println("输入的不是一个有效的字母!");
}
// 4. 获取并处理是否同意条款
System.out.print("您是否同意我们的服务条款? (true/false): ");
boolean agree = Boolean.parseBoolean(scanner.nextLine()); // 使用Boolean包装类将字符串转换为布尔值
// 输出收集到的信息
System.out.println("感谢您的输入!");
System.out.println("您的年龄是: " + age);
System.out.println("您的身高是: " + height + " 米");
System.out.println("您是否同意条款: " + agree);
// 关闭scanner,防止资源泄露
scanner.close();
}
}
代码解释和总结:
- 创建Scanner对象:我们创建了一个Scanner对象,它可以帮助我们从控制台读取用户输入的内容。就像你有一个工具可以抓取键盘上输入的东西一样。
- 年龄转换:用户输入的年龄是以字符串的形式提供的,但我们需要它作为整数来处理。所以,我们使用了Integer.parseInt()方法,它就像是一个魔法棒,可以把看起来像数字的字符串变成真正的数字。
- 身高转换:与年龄类似,用户输入的身高也是以字符串的形式提供的,但我们希望它是可以用来计算的数字,所以我们使用了Double.valueOf()方法。这个方法不仅可以把字符串变成数字,还可以直接返回一个Double对象,这在某些情况下会更方便。
- 名字首字母检查:用户输入的名字首字母可能是一个字母,也可能不是。为了确保我们得到的是一个字母,我们使用了Character.isLetter()方法。如果用户输入的是字母,它就会告诉我们;如果不是,我们也会知道,并且可以给出提示。
- 条款同意:用户需要告诉我们他们是否同意服务条款,他们可以用"true"或"false"来回答。我们使用Boolean.parseBoolean()方法来理解用户的回答。这个方法很聪明,它可以识别出"true"表示同意,其他任何输入都被认为是不同意。
- 输出信息:最后,我们把所有收集到的信息整理成一句话,告诉用户我们已经收到了他们的输入。
- 关闭Scanner:当我们完成了所有的工作后,记得要关闭Scanner,这样可以释放系统资源,就像用完东西后要收拾好一样。
自定义包装类
概述:
什么是自定义包装类:
官方定义:
自定义包装类(Custom Wrapper Class)是开发者根据特定需求设计的类,用于封装基本数据类型或其他对象,并提供额外的功能或行为。虽然Java已经为每种基本数据类型提供了标准的包装类(如Integer, Double等),但在某些情况下,你可能需要创建自己的包装类来满足特定的应用场景或业务逻辑。
大白话拆解:
有一个玩具盒子(基本数据类型),里面可以放一些小玩具(比如数字、字符等)。
但是有时候,你想要给这些玩具添加一些特别的功能(武器附魔,开发新玩法,新功能),或者把它们打扮得更漂亮。这时候,你可以制作一个特制的盒子(自定义包装类),这个盒子不仅能够装下你的玩具,还可以按照人性化的自定义为这些玩具提供额外的“魔法”功能。
在编程中,自定义包装类就是我们自己设计的一个类,用来包裹(或封装)基本数据类型或者其他对象。它不仅可以保存数据,还能提供一些额外的方法和属性,让这些数据变得更加有用和易于操作
如何声明自定义包装类
声明自定义包装类的过程与其他普通类类似,但重点在于如何封装数据和提供相应的操作方法。下面是一个简单的例子,展示如何创建一个自定义包装类来封装整数,并提供一些额外的方法。
举个栗子:
public class CustomInteger {
// 私有字段,用于存储被封装的整数值
private int value;
// 构造方法,用于初始化包装类实例
public CustomInteger(int value) {
this.value = value;
}
// getter方法,用于获取封装的整数值
public int getValue() {
return value;
}
// setter方法,用于设置新的整数值
public void setValue(int value) {
this.value = value;
}
// 额外的方法,例如将整数值翻倍
public int doubleValue() {
return value * 2;
}
// 额外的方法,例如检查整数值是否为偶数
public boolean isEven() {
return value % 2 == 0;
}
// 重写toString方法,以便更友好地显示对象信息
@Override
public String toString() {
return "CustomInteger{" +
"value=" + value +
'}';
}
// 主方法,用于测试自定义包装类
public static void main(String[] args) {
// 创建CustomInteger对象
CustomInteger customInt = new CustomInteger(10);
// 使用自定义包装类的方法
System.out.println("Original value: " + customInt.getValue());
System.out.println("Doubled value: " + customInt.doubleValue());
System.out.println("Is even? " + customInt.isEven());
// 修改值并再次使用方法
customInt.setValue(7);
System.out.println("Updated value: " + customInt.getValue());
System.out.println("Is even? " + customInt.isEven());
// 打印对象信息
System.out.println(customInt.toString());
}
}
代码解释和总结:
1. 声明自定义包装类
- 首先,我们来看看如何声明一个自定义包装类。在Java中,创建一个新的类就像是设计一种新的“盒子”,这个盒子可以用来装特定类型的数据,并提供一些额外的功能。
- 在这段代码中,我们创建了一个名为CustomInteger的类,它用来封装(或包装)一个整数(int)。你可以把CustomInteger想象成一个特别的盒子,里面装着一个整数,而且这个盒子还有一些特殊的魔法功能。
public class CustomInteger {
// 私有字段,用于存储被封装的整数值
private int value;
- private int value;:这里我们定义了一个私有的字段value,它用来存储整数值。为什么是私有的呢?因为我们要保护这个数据,不让外界直接修改它。这就像是你有一个秘密宝藏,不想让别人随便拿走,所以把它藏起来。
2. 构造方法
- 接下来,我们需要一个方法来初始化这个“盒子”,也就是当我们创建一个新的CustomInteger对象时,告诉它里面要装什么数字。
// 构造方法,用于初始化包装类实例
public CustomInteger(int value) {
this.value = value;
}
- public CustomInteger(int value):这是构造方法,它的名字和类名一样,没有返回类型。当我们创建一个新的CustomInteger对象时,会调用这个方法。它接受一个整数参数value,并将其赋值给类内部的value字段。这就像你在制作一个盒子时,告诉它里面要放哪个数字。
3. Getter 和 Setter 方法
- 为了让外界能够安全地访问和修改这个“盒子”里的数字,我们需要提供一些方法。这些方法就像是盒子上的小窗口和锁,让我们可以查看或改变里面的数字,但不会破坏盒子的安全性。
// getter方法,用于获取封装的整数值
public int getValue() {
return value;
}
// setter方法,用于设置新的整数值
public void setValue(int value) {
this.value = value;
}
- getValue():这个方法允许我们查看“盒子”里的数字。它返回value的当前值。
- setValue(int value):这个方法允许我们修改“盒子”里的数字。它接受一个新的整数参数,并将其赋值给value字段。
4. 额外的方法
- 为了让我们的“盒子”更有用,我们可以添加一些额外的方法,这些方法可以对“盒子”里的数字进行操作。比如,我们可以添加一个方法来将数字翻倍,或者检查数字是否为偶数。
// 额外的方法,例如将整数值翻倍
public int doubleValue() {
return value * 2;
}
// 额外的方法,例如检查整数值是否为偶数
public boolean isEven() {
return value % 2 == 0;
}
- doubleValue():这个方法将“盒子”里的数字乘以2,并返回结果。它就像是一个魔法按钮,按一下就能让数字变成原来的两倍。
- isEven():这个方法检查“盒子”里的数字是否为偶数。如果数字能被2整除,它就返回true,否则返回false。
5. 重写 toString 方法
- 为了让我们的“盒子”在打印时更友好地显示信息,我们可以重写toString方法。这个方法决定了当我们将对象转换为字符串时,应该输出什么内容。
// 重写toString方法,以便更友好地显示对象信息
@Override
public String toString() {
return "CustomInteger{" +
"value=" + value +
'}';
}
- toString():这个方法返回一个字符串,描述了“盒子”里的内容。它会输出类似CustomInteger{value=10}这样的信息,这样当你打印对象时,可以看到里面的具体数字。
6. 主方法(测试代码)
- 最后,我们编写一个main方法来测试我们的CustomInteger类。这个方法就像是一个实验场,我们可以在这里创建对象并调用各种方法,看看它们是否按预期工作。
// 主方法,用于测试自定义包装类
public static void main(String[] args) {
// 创建CustomInteger对象
CustomInteger customInt = new CustomInteger(10);
// 使用自定义包装类的方法
System.out.println("Original value: " + customInt.getValue());
System.out.println("Doubled value: " + customInt.doubleValue());
System.out.println("Is even? " + customInt.isEven());
// 修改值并再次使用方法
customInt.setValue(7);
System.out.println("Updated value: " + customInt.getValue());
System.out.println("Is even? " + customInt.isEven());
// 打印对象信息
System.out.println(customInt.toString());
}
- CustomInteger customInt = new CustomInteger(10);:我们创建了一个CustomInteger对象,并初始化它为10。这就像是我们做了一个新的盒子,并在里面放了数字10。
- System.out.println(...):我们使用System.out.println来打印各种信息,包括原始值、翻倍后的值、是否为偶数等。
- customInt.setValue(7);:我们使用setValue方法将“盒子”里的数字改为7,然后再次调用方法查看结果。
- System.out.println(customInt.toString());:最后,我们打印整个对象的信息,看看它现在的状态。
小编今天先讲到这里,我们下次再见!!!