Java高级语法详解之包装类
- :one: 概念
- :two: 设计目的(作用)和用途
- :three: 使用
- 3.1 自动装箱与拆箱
- 3.2 常用方法
- 3.3 常用属性
- 3.4 null和默认值
- :four: 注意事项
- :ear_of_rice: 总结
- :bookmark_tabs: 本文源码下载地址
1️⃣ 概念
在Java编程中,包装类(Wrapper Class)是一种特殊的类,它们允许将基本数据类型包装(Wrap)成对象。每个原始数据类型都有对应的包装类,例如Integer
对应整型,Double
对应浮点型等。包装类提供了一些有用的方法和功能,方便我们操作和处理与原始数据类型相关的数据。
Java中的8个基本数据类型分别为boolean
、byte
、short
、int
、long
、float
、double
、char
。每个基本数据类型都有相应的包装类,它们分别为:Boolean
、Byte
、Short
、Integer
、Long
、Float
、Double
、Character
。
包装类是不可变的,即创建后不能修改其值。它们的对象可以通过构造函数或静态工厂方法来创建,并且提供了许多方法用于转换、比较和操作基本数据类型的值。
2️⃣ 设计目的(作用)和用途
包装类主要有以下几个设计目的和用途:
-
将原始数据类型转化为对象类型: 用于支持面向对象编程。原始数据类型(如int、float等)在Java中是不具备面向对象特性的,不能直接作为对象在方法中传递或进行其他操作。包装类为每种原始数据类型提供了一个对应的对象类型,使得原始数据类型可以以对象的形式进行操作;
-
实现与原始数据类型相关的功能: 包装类提供了一系列的方法,用于对原始数据类型及其对象进行常见操作,如转换、比较、计算等。这些方法往往在编程过程中非常有用,并且方便使用;
-
泛型支持: 在需要引用类型而基本数据类型不可用的情况下使用。泛型只能接受引用类型作为参数,而不能直接使用原始数据类型。通过使用包装类,我们可以将原始数据类型作为对象传递给泛型类或方法;
-
null值表示缺失或特殊状态: 对于原始数据类型,没有办法表示一个缺失的值或特殊状态,因为它们是值类型而不是引用类型。包装类通过提供
null
值来表示缺失的值或特殊状态,例如在数据库中查询到的结果为空。
总之,包装类的设计使得原始数据类型可以以对象的形式出现,并提供了一些常用方法和功能来处理、操作和表示与原始数据类型相关的数据。
3️⃣ 使用
3.1 自动装箱与拆箱
在Java中,自动装箱(Autoboxing)指的是自动地将基本数据类型转换为对应的包装类对象;自动拆箱(Unboxing)则是将包装类对象自动转换为基本数据类型。
下面是一个简单的示例,展示了如何使用自动装箱与拆箱:
public class BoxingDemo {
public static void main(String[] args) {
// 自动装箱
Integer num1 = 10; // 等价于 下面这行代码
Integer num2 = Integer.valueOf(10);
// 自动拆箱
int num3 = num1; // 等价于 下面这行代码
int num4 = num1.intValue();
System.out.println(num1 == num2);
System.out.println(num1.equals(num2));
System.out.println(num3 == num4);
}
}
在程序中,Integer num1 = 10;
这行代码,整数10被自动装箱成一个Integer
对象,并赋值给变量num1
。实际上,这行代码等价于 Integer num2 = Integer.valueOf(10);
使用了包装类的valueOf
方法手动进行装箱。
而int num3 = num1;
这行代码中,num1
表示的Integer
对象被自动拆箱为对应的基本数据类型int
并赋值给num3
。实际上,这行代码等价于 int num4 = num1.intValue();
手动调用intValue
方法进行拆箱。
接下来的三个输出语句用于比较两个对象的引用和值是否相等:
System.out.println(num1 == num2);
检查num1
和num2
是否引用同一个对象。由于装箱操作时会缓存一定范围内的包装类对象,所以当数值范围在-128到127之间时,两个引用将指向同一个对象,输出结果为true
。对于其他数值范围,不同的装箱操作将创建新的对象,输出结果为false
;System.out.println(num1.equals(num2));
使用equals
方法检查num1
和num2
的值是否相等。无论数值范围如何,此比较都会比较对象存储的数值,输出结果为true
;System.out.println(num3 == num4);
检查num3
和num4
的值是否相等。由于拆箱操作直接比较基本数据类型的值,输出结果为true
。
输出结果:
true
true
true
3.2 常用方法
包装类中的常见方法如下:
XXXValue()
方法:将包装类对象转换为相应的基本数据类型;parseXXX(String s)
方法:将字符串转换为相应的基本数据类型;toString()
方法:将包装类对象转换为字符串形式;equals()
方法:比较两个包装类对象是否相等;compare()
方法:比较两个包装类对象的大小关系。若第一个对象小于第二个对象,则返回一个负数;若两个对象相等,则返回0;若第一个对象大于第二个对象,则返回一个正数;valueOf()
方法:返回一个包含指定值的包装类对象。该方法是装箱的一种方式。
下面是一个简单的示例,展示了如何使用包装类中的这些常见方法:
public class MethodDemo {
public static void main(String[] args) {
// 使用intValue()方法将Integer转为int
Integer number1 = new Integer(10);
int value1 = number1.intValue();
System.out.println("intValue(): " + value1);
// 使用parseInt()方法将字符串转为int
String str = "20";
int value2 = Integer.parseInt(str);
System.out.println("parseInt(): " + value2);
// 使用toString()方法将int转为字符串
int number3 = 30;
String str2 = Integer.toString(number3);
System.out.println("toString(): " + str2);
// 使用equals()方法比较两个Integer对象是否相等
Integer number4 = new Integer(40);
Integer number5 = new Integer(40);
boolean isEqual = number4.equals(number5);
System.out.println("equals(): " + isEqual);
// 使用compare()方法比较两个int值的大小
int value3 = 50;
int value4 = 60;
int result = Integer.compare(value3, value4);
System.out.println("compare(): " + result);
// 使用valueOf()方法将int转为Integer对象
int number6 = 70;
Integer value5 = Integer.valueOf(number6);
System.out.println("valueOf(): " + value5);
}
}
输出结果:
intValue(): 10
parseInt(): 20
toString(): 30
equals(): true
compare(): -1
valueOf(): 70
3.3 常用属性
除了上述通用方法,每个包装类还提供了特定类型的方法和属性:
- Integer类:
MAX_VALUE
:表示整型的最大值;MIN_VALUE
:表示整型的最小值;SIZE
:表示整型的位数;TYPE
:表示数据类型的Class对象。
- Double类:
MAX_VALUE
:表示双精度浮点型的最大值;MIN_VALUE
:表示双精度浮点型的最小值;NaN
:表示非数字值;POSITIVE_INFINITY
:表示正无穷大;NEGATIVE_INFINITY
:表示负无穷大。
- Character类:
MIN_VALUE
:表示字符型的最小值;MAX_VALUE
:表示字符型的最大值;TYPE
:表示数据类型的Class对象。
- Boolean类:
TRUE
:表示真值;FALSE
:表示假值。
- …
以上只是列举了常用的属性字段,并不是全部。每个包装类还提供其他方法和属性,具体可以参考相关文档及源码或查阅Java API文档以获得更详细的信息。
3.4 null和默认值
包装类可以具有null
值,表示没有有效的值。这在需要处理可能不存在的值时非常有用。如果没有给包装类对象赋初始值,则它的默认值为null
。
下面是一个简单的示例,展示了包装类中的初始默认值:
public class DefaultValueDemo {
public static void main(String[] args) {
Integer num = null;
System.out.println(num);
Integer num2 = new Integer("1");
System.out.println(num2);
}
}
Integer num = null;
: 这行代码声明了一个名为num
的Integer
类型变量,并将其初始化为null
。null
表示该变量当前不引用任何对象。Integer num2 = new Integer("1");
: 这行代码创建了一个名为num2
的Integer
类型变量,并使用字符串"1"作为初始值来实例化它。通过将字符串转换为对应的整数值,num2
将被赋值为整数1。
输出结果:
null
1
4️⃣ 注意事项
自动装箱与拆箱带来的性能问题:
虽然自动装箱和拆箱提供了简洁的代码,但在性能方面需要谨慎。由于装箱和拆箱操作涉及创建对象和类型转换,会带来额外的开销。因此,在处理大量数据时,使用基本数据类型可能更高效。
要规避包装类自动装箱和拆箱的性能问题,可以考虑以下几种方法:
- 显式使用基本数据类型:尽量使用基本数据类型而不是对应的包装类。这样可以避免自动装箱和拆箱的开销;
- 使用静态工厂方法创建包装类实例:在必须使用包装类时,可以使用静态工厂方法(如
Integer.valueOf(int)
)来创建包装类的实例。静态工厂方法会经过一定的缓存优化,可以重用已有对象,减少对象的创建和销毁; - 使用原始类型数组:如果需要存储大量的基本数据类型,可以使用原始类型数组而不是包装类数组。原始类型数组效率更高,因为它们不会涉及到装箱和拆箱的操作;
- 避免使用包装类进行运算: 避免使用包装类进行大量的数学运算,特别是在循环中进行运算。相比之下,使用基本数据类型可以获得更好的性能;
- 使用第三方库:如果性能问题是严重的,可以考虑使用第三方库,如Trove或FastUtil,它们提供了基于原始类型的高性能集合类。
需要注意的是,自动装箱和拆箱的性能问题通常在处理大量数据时才会显著影响性能。对于一般的应用程序,这些性能差异可能不太明显,在编写代码时应根据具体情况权衡性能和可读性。
🌾 总结
总的来说,Java的包装类提供了将基本数据类型转换为对象的机制,并且提供了一些有用的方法和属性来处理这些封装后的值。这些包装类在编程中经常被使用,特别是在集合类框架和需要处理基本数据类型的情况下。
可以说包装类是一种强大的工具,它们在处理基本数据类型时提供了更多的灵活性和功能。掌握包装类及其相关知识对于开发Java应用程序非常重要,尤其是在处理用户输入、数据库操作和集合框架等方面。
但同时,在使用包装类时,需要注意自动装箱和拆箱带来的性能方面的问题,因为装箱和拆箱操作涉及创建对象和类型转换,会带来额外的开销。
📑 本文源码下载地址
Java语言 包装类讲解案例代码 ( 设计目的(作用)和用途、自动装箱与拆箱、常用方法、 null和默认值)