Java内置包装类
Q7nl1s admin

Java内置的包装类

Java包装类、装箱和拆箱

Java的内置包装类很简单,它的出现也是有原因的,由于Java中的数据类型包含了基本数据类型和引用数据类型,但是基本数据类型并不能直接被称作对象,所以Java为每种基本数据类型都创建了对应的类,并将其称作包装类(外覆类或数据类型类)。

基本数据类型对应的包装类如表6-0所示。

序号 基本数据类型 包装类
1 byte Byte
2 short Short
3 int Integer
4 long Long
5 char Character
6 float Float
7 double Double
8 boolean Boolean

表6-0 基本数据类型及其对应的包装类

装箱和拆箱

概念辨析:基本数据类型转换为包装类的过程称为装箱,例如把 int 包装成 Integer 类的对象;包装类变为基本数据类型的过程称为拆箱,例如把 Integer 类的对象重新简化为 int。

手动实例化一个包装类称为装箱。Java 1.5版本之前必须手动装拆箱,之后可以自动拆装箱。下面分别给出手动装拆箱和自动装拆箱的案例:

自动拆装箱

1
2
3
4
5
6
7
8
9
10
11
public class Demo {
public static void main(String[] args) {
int m = 500;
Integer obj = m; // 自动装箱
int n = obj; // 自动拆箱
System.out.println("n = " + n);

Integer obj1 = 500;
System.out.println("obj等价于obj1返回结果为" + obj.equals(obj1));
}
}

运行结果:

1
2
n = 500
obj等价于obj1返回结果为true

手动拆装箱

1
2
3
4
5
6
7
8
9
10
11
public class Demo {
public static void main(String[] args) {
int m = 500;
Integer obj = new Integer(m); // 手动装箱
int n = obj.intValue(); // 手动拆箱
System.out.println("n = " + n);

Integer obj1 = new Integer(500);
System.out.println("obj等价于obj1的返回结果为" + obj.equals(obj1));
}
}

运行结果:

1
2
n = 500
obj等价于obj1的返回结果为true

包装类的应用

包装类的常见应用有三种:

  • 实现 int 和 Integer 的相互转换(手动/自动拆装箱)
  • 将字符串转换为数值类型
  • 将整数转换为字符串

下面给出后面两种的案例。

将字符串转换为数值类型

① Integer 类(String 转 int 型)

1
int parseInt(String s);

s 为要转换的字符串。

② Float 类(String 转 float 型)

1
float parseFloat(String s)

注意:使用以上两种方法时,字符串中的数据必须由数字组成,否则转换时会出现程序错误。

将整数转换为字符串

很多基本类型的包装类都有一个静态的toString()方法,可以将整数转换为字符串。例如:

1
2
3
4
5
6
7
public class Demo {
public static void main(String[] args) {
int m = 500;
String s = Integer.toString(m);
System.out.println("s = " + s);
}
}

运行结果:

1
s = 500

由于篇幅过长,我只挑选几个经典的基本数据类型的包装类来分析。

Java Object类

Object是Java类库中的一个特殊类,也是所有类的父类。因此,Java允许把任何类型的对象付给Object类型的变量。当一个类被定义后,如果没有指定继承的父类,那么默认父类就是Object类。因此如下的两个类表示的含义是一样的。

1
public class MyClass{...}

等价于

1
public class MyClass extends Object{...}

注:entends是Java中的一个动作,语句public class A entends B{...}的含义是,类A继承自类B或者说类B派生出类A

下面为Object类的常用方法

方法 说明
Object clone() 创建与该对象的类相同的新对象
boolean equals(Object) 比较两对象是否相等
void finalize() 当垃圾回收器确定不存在对该对象的更多引用时,对象垃圾回收器调用该方法
Class getClass() 返回一个对象运行时的实例类
int hashCode() 返回该对象的散列码值
void notify() 激活等待在该对象的监视器上的一个线程
void notifyAll() 激活等待在该对象的监视器上的全部线程
String toString() 返回该对象的字符串表示
void wait() 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待

表6-1 Object 类的常用方法

其中toString()、equals()和getClass()方法在Java程序中较为常见,我也只简单介绍一下这三者。

ToString()方法

当程序输出一个对象或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的 toString() 方法返回该对象的字符串表示。

Object 类的 toString() 方法返回“运行时类名@十六进制哈希码”格式的字符串,但很多类都重写了 Object 类的 toString() 方法,用于返回可以表述该对象信息的字符串。

哈希码(hashCode),每个 Java 对象都有哈希码属性,哈希码可以用来标识对象,提高对象在集合操作中的执行效率。

先看以下代码:

1
2
3
4
5
6
7
8
9
10
// 定义Demo类,实际上继承Object类
class Demo {
}
public class ObjectDemo01 {
public static void main(String[] args) {
Demo d = new Demo(); // 实例化Demo对象
System.out.println("不加toString()输出:" + d);
System.out.println("加上toString()输出:" + d.toString());
}
}

输出结果为:

1
2
不加toString()输出:Demo@15db9742
加上toString()输出:Demo@15db9742

以上的程序是随机输出了一些地址信息,从程序的运行结果可以清楚的发现,加和不加 toString() 的最终输出结果是一样的,也就是说对象输出时一定会调用 Object 类中的 toString() 方法打印内容。所以利用此特性就可以通过 toString() 取得一些对象的信息,如下面代码。

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
toString() 方法返回该对象的字符串,当程序输出一个对象或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的 toString() 方法返回该对象的字符串表示。

Object 类的 toString() 方法返回“运行时类名@十六进制哈希码”格式的字符串,但很多类都重写了 Object 类的 toString() 方法,用于返回可以表述该对象信息的字符串。
哈希码(hashCode),每个 Java 对象都有哈希码属性,哈希码可以用来标识对象,提高对象在集合操作中的执行效率。

先看以下代码:
// 定义Demo类,实际上继承Object类
class Demo {
}
public class ObjectDemo01 {
public static void main(String[] args) {
Demo d = new Demo(); // 实例化Demo对象
System.out.println("不加toString()输出:" + d);
System.out.println("加上toString()输出:" + d.toString());
}
}
输出结果为:
不加toString()输出:Demo@15db9742
加上toString()输出:Demo@15db9742

以上的程序是随机输出了一些地址信息,从程序的运行结果可以清楚的发现,加和不加 toString() 的最终输出结果是一样的,也就是说对象输出时一定会调用 Object 类中的 toString() 方法打印内容。所以利用此特性就可以通过 toString() 取得一些对象的信息,如下面代码。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "姓名:" + this.name + ":年龄" + this.age;
}
public static void main(String[] args) {
Person per = new Person("C语言中文网", 30);// 实例化Person对象
System.out.println("对象信息:" + per);// 打印对象调用toString()方法
}
}
输出结果为:
对象信息:姓名:C语言中文网:年龄30

程序中的 Person 类中重写了 Object 类中的 toString() 方法,这样直接输出对象时调用的是被子类重写过的 toString() 方法。

输出结果为:

对象信息:姓名:C语言中文网:年龄30

程序中的 Person 类中重写了 Object 类中的 toString() 方法,这样直接输出对象时调用的是被子类重写过的 toString() 方法。

equals()方法

equals() 方法是比较两个对象的内容是否相等,通常字符串的比较只是关心内容是否相等。

1
boolean result = obj.equals(Object o);
  • obj:要进行比较的一个对象
  • o :另一个对象。

getClass() 方法

getClass() 方法返回对象所属的类,是一个 Class 对象。通过 Class 对象可以获取该类的各种信息,包括类名、父类以及它所实现接口的名字等。

下面给出实例:

编写一个实例,演示如何对 String 类型调用 getClass() 方法,然后输出其父类及实现的接口信息。具体实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Test02 {
public static void printClassInfo(Object obj) {
// 获取类名
System.out.println("类名:" + obj.getClass().getName());
// 获取父类名
System.out.println("父类:" + obj.getClass().getSuperclass().getName());
System.out.println("实现的接口有:");
// 获取实现的接口并输出
for (int i = 0; i < obj.getClass().getInterfaces().length; i++) {
System.out.println(obj.getClass().getInterfaces()[i]);
}
}
public static void main(String[] args) {
String strObj = new String();
printClassInfo(strObj);
}
}

该程序的运行结果如下:

1
2
3
4
5
6
类名:java.lang.String
父类:java.lang.Object
实现的接口有:
interface java.io.Serializable
interface java.lang.Comparable
interface java.lang.CharSequence

接收任意引用类型的对象

既然 Object 类是所有对象的父类,则所有的对象都可以向 Object 进行转换,在这其中也包含了数组和接口类型,即一切的引用数据类型都可以使用 Object 进行接收。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
interface A {
public String getInfo();
}
class B implements A {
public String getInfo() {
return "Hello World!!!";
}
}
public class ObjectDemo04 {
public static void main(String[] args) {
// 为接口实例化
A a = new B();
// 对象向上转型
Object obj = a;
// 对象向下转型
A x = (A) obj;
System.out.println(x.getInfo());
}
}

输出结果为:

1
Hello World!!!

通过以上代码可以发现,虽然接口不能继承一个类,但是依然是 Object 类的子类,因为接口本身是引用数据类型,所以可以进行向上转型操作。

同理,也可以使用 Object 接收一个数组,因为数组本身也是引用数据类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ObjectDemo05 {
public static void main(String[] args) {
int temp[] = { 1, 3, 5, 7, 9 };
// 使用object接收数组
Object obj = temp;
// 传递数组引用
print(obj);
}
public static void print(Object o) {
// 判断对象的类型
if (o instanceof int[]) {
// 向下转型
int x[] = (int[]) o;
// 循环输出
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + "\t");
}
}
}
}

输出结果为:

1
1 3 5 7 9

[Java instanceof用法详解](Java instanceof用法详解_Cappuccinooo的博客-CSDN博客_instanceof java):instanceof是 Java 的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。关于它的说明有两个点要注意:

  • 类的实例包含本身的实例,以及所有直接或间接子类的实例

  • instanceof左边显式声明的类型与右边操作元必须是同种类或存在继承关系,也就是说需要位于同一个继承树,否则会编译错误

在使用它时又有三个要注意的点:

  • 左边的对象实例不能是基础数据类型
  • 左边的对象实例和右边的类必须在同一个继承树上
  • null用instanceof跟任何类型比较时都是false

以上程序使用 Object 接收一个整型数组,因为数组本身属于引用数据类型,所以可以使用 Object 接收数组内容,在输出时通过 instanceof 判断类型是否是一个整型数组,然后进行输出操作。

提示:因为 Object 类可以接收任意的引用数据类型,所以在很多的类库设计上都采用 Object 作为方法的参数,这样操作起来会比较方便。

Java Integer类

Integer类在对象中包装了一个基本类型int的值。Integer类对象包含一个int类字段。

两种构造方法:

1
2
Integer integer1 = new Integer(100);    // 以 int 型变量作为参数创建 Integer 对象
Integer integer2 = new Integer("100"); // 以 String 型变量作为参数创建 Integer 对象

Integer 类的常用方法

如表6-2所示

方法 返回值 功能
byteValue() byte 以 byte 类型返回该 Integer 的值
shortValue() short 以 short 类型返回该 Integer 的值
intValue() int 以 int 类型返回该 Integer 的值
toString() String 返回一个表示该 Integer 值的 String 对象
equals(Object obj) boolean 比较此对象与指定对象是否相等
compareTo(Integer anotherlnteger) int 在数字上比较两个 Integer 对象,如相等,则返回 0; 如调用对象的数值小于 anotherlnteger 的数值,则返回负值; 如调用对象的数值大于 anotherlnteger 的数值,则返回正值
valueOf(String s) Integer 返回保存指定的 String 值的 Integer 对象
parseInt(String s) int 将数字字符串转换为 int 数值

表6-2 Integer类中的常用方法

在实际编程中可通过parseInt(str)方法和toString()方法分别来进行int和str类型的相互转换。

Integer类的常量

Integer类包含以下四个常量:

  • MAX_VALUE:值为 231-1 的常量,它表示 int 类型能够表示的最大值。
  • MIN_VALUE:值为 -231 的常量,它表示 int 类型能够表示的最小值。
  • SIZE:用来以二进制补码形式表示 int 值的比特位数。
  • TYPE:表示基本类型 int 的 Class 实例。

下面的代码演示了 Integer 类中常量的使用。

1
2
3
4
int max_value = Integer.MAX_VALUE;    // 获取 int 类型可取的最大值
int min_value = Integer.MIN_VALUE; // 获取 int 类型可取的最小值
int size = Integer.SIZE; // 获取 int 类型的二进制位
Class c = Integer.TYPE; // 获取基本类型 int 的 Class 实例

Java Double类

与Integer类相似,Double类在对象中包装了一个基本类型double的值。Double类对象包含一个double类型的字段。

两种构造方法:

  • Double(double value):构造一个新分配的 Double 对象,它表示转换为 double 类型的参数。
  • Double(String s):构造一个新分配的 Double 对象,它表示 String 参数所指示的 double 值。

下面分别用两种构造方法获取Double类的对象:

1
2
Double double1 = new Double(5.456);    // 以 double 类型的变量作为参数创建 Double 对象
Double double2 = new Double("5.456"); // 以 String 类型的变量作为参数创建 Double 对象

Double 类的常用方法

Double类的常用方法如表6-3所示。

方法 返回值 功能
byteValue() byte 以 byte 类型返回该 Double 的值
doubleValue() double 以 double 类型返回该 Double 的值
fioatValue() float 以 float 类型返回该 Double 的值
intValue() int 以 int 类型返回该 Double 的值(强制转换为 int 类型)
longValue() long 以 long 类型返回该 Double 的值(强制转换为 long 类型)
shortValue() short 以 short 类型返回该 Double 的值(强制转换为 short 类型)
isNaN() boolean 如果此 Double 值是一个非数字值,则返回 true,否则返回 false
isNaN(double v) boolean 如果指定的参数是一个非数字值,则返回 true,否则返回 false
toString() String 返回一个表示该 Double 值的 String 对象
valueOf(String s) Double 返回保存指定的 String 值的 Double 对象
parseDouble(String s) double 将数字字符串转换为 Double 数值

表6-3 Double类中的常用方法

Double 类的常用常量

在 Double 类中包含了很多常量,其中较为常用的常量如下。

  • MAX_VALUE:值为 1.8E308 的常量,它表示 double 类型的最大正有限值的常量。
  • MIN_VALUE:值为 4.9E-324 的常量,它表示 double 类型数据能够保持的最小正非零值的常量。
  • NaN:保存 double 类型的非数字值的常量。
  • NEGATIVE_INFINITY:保持 double 类型的负无穷大的常量。
  • POSITIVE_INFINITY:保持 double 类型的正无穷大的常量。
  • SIZE:用秦以二进制补码形式表示 double 值的比特位数。
  • TYPE:表示基本类型 double 的 Class 实例。

Java Numebr类

Number是一个抽象类,也是一个超类(即父类)。Number类属于java.lang包,所有的包装类(如Double、Float、Byte、Short、Integer以及Long)都是抽象类Number的子类。

Number类中定义了一些抽象方法,以及各种不同数字格式返回对象的值。如xxxValue()方法,它将Number对象转换为xxx数据类型的值并返回。具体如表6-4所示:

方法 说明
byte byteValue(); 返回 byte 类型的值
double doubleValue(); 返回 double 类型的值
float floatValue(); 返回 float 类型的值
int intValue(); 返回 int 类型的值
long longValue(); 返回 long 类型的值
short shortValue(); 返回 short 类型的值

表6-4 Number类的方法

Java System类

System类位于java.lang包,代表当前Java程序的运行平台,系统级的很多属性和方法否放置在该类的内部。由于改了的构造方法是private的,所以无法创建该类的对象,也就是无法实例化该类。

System 类的成员变量

System类有3个静态成员变量,分别是PrintSteam out、InputStream in、PrintStream err。

1.PrintStream out

标准输出流。编写一行数据数据的典型方式如下:

1
System.out.println(date);

注意:println()方法是属于六类PrintStream的方法而不是System中的方法。

2.InputStream in

标准输出流。语法与System.out类似,不需要提供参数就可输出错误信息。也可以用来输出用户指定的其它信息,包括变量的值。

具体的System类的标准输入输出流使用案例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.io.IOException;
public class Test06 {
public static void main(String[] args) {
System.out.println("请输入字符,按回车键结束输入:");
int c;
try {
c = System.in.read(); // 读取输入的字符
while(c != '\r') { // 判断输入的字符是不是回车
System.out.print((char) c); // 输出字符
c = System.in.read();
}
} catch(IOException e) {
System.out.println(e.toString());
} finally {
System.err.println();
}
}
}

以上程序如果输入汉字将不能正常输出。如果要正常输出汉字,需要把System.in声明为InputStreamReader类型的实例,最终在try语句块中的代码为:

1
2
3
4
5
6
InputStreamReader in = new InputStreamReader(System.in, "GB2312");
c = in.read();
while(c != '\r') {
System.out.print((char) c);
c = in.read();
}

System类的成员方法

System类中提供了一些系统级的操作方法,常用的方法有arraycopy()、currentTimeMillis()、exit()、gc()和getProperty()。

下面简单介绍一下这些方法:

1. arraycopy() 方法

该方法的作用是数组复制,即从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。该方法的具体定义如下:

1
public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)
  • src :源数组
  • srcPos :从源数组中复制的起始位置
  • dest :目标数组
  • destPos :要复制到的目标数组的起始位置
  • length :复制的个数。

2. currentTimeMillis() 方法

该方法的作用是返回当前的计算机时间,时间的格式为当前计算机时间与 GMT 时间(格林尼治时间)1970 年 1 月 1 日 0 时 0 分 0 秒所差的毫秒数。一般用它来测试程序的执行时间。例如:

1
long m = System.currentTimeMillis();

上述语句将获得一个长整型的数字,该数字就是以差值表达的当前时间。

3. exit() 方法

该方法的作用是终止当前正在运行的 Java 虚拟机,具体的定义格式如下:

1
public static void exit(int status)

其中,status 的值为 0 时表示正常退出,非零时表示异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。

4. gc() 方法

该方法的作用是请求系统进行垃圾回收,完成内存中的垃圾清除。至于系统是否立刻回收,取决于系统中垃圾回收算法的实现以及系统执行时的情况。定义如下:

1
public static void gc()

5.getProperty() 方法

该方法的作用是获得系统中属性名为 key 的属性对应的值,具体的定义如下:

1
public static String getProperty(String key)

系统中常见的属性名以及属性的说明如表6-5 所示。

属性名 属性说明
java.version Java 运行时环境版本
java.home Java 安装目录
os.name 操作系统的名称
os.version 操作系统的版本
user.name 用户的账户名称
user.home 用户的主目录
user.dir 用户的当前工作目录

表6-5 系统常见属性

 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
Unique Visitor Page View