7.3 常用类 7.3.1 Object类

7.3 常用类

本节将介绍Java提供的一些常用类,如StringMathBigDecimal等的用法

7.3.1 Object类

Object类是所有数组枚举类的父类,也就是说,Java允许把任何类型的对象赋给Object类型的变量。

当定义一个类时没有使用extends关键字为它显式指定父类,则该类默认继承Object父类。

因为所有的Java类都是Object类的子类,所以任何Java对象都可以调用Object类的方法。

Object类常用方法

Object类提供了如下几个常用方法

常用方法

方法 描述
boolean equals(Object obj) 判断指定对象与该对象是否相等。如果两个对象是同一个对象,则Object类认为这两个对象相等。因此该equals方法通常没有太大的实用价值。
int hashCode() 返回该对象的hash Code值。在默认情况下, Object类的hashCode()方法根据该对象的地址来计算(即与System.identityHashCode(Object x)方法的计算结果相同)。但很多类都重写了Object类的hashCode()方法,不再根据地址来计算其hashCode()方法值。
String toString() 返回该对象的字符串表示,当程序使用System.out.printIn()方法输出一个对象,或者把某个对象和字符串进行连接运算时,系统会自动调用该对象的toString()方法返回该对象的字符串表示。 Object类的toString方法返回"运行时类名@十六进制hashCode值"格式的字符串,但很多类都重写了Object类的toString方法,用于返回可以表述该对象信息的字符串.

垃圾回收相关方法

方法 描述
protected void finalize() 当系统中没有引用变量引用到该对象时,垃圾回收器调用此方法来清理该对象的资源

反射相关方法

方法 描述
Class<?> getClass() 返回该对象的运行时类。

Object中进程相关的方法

除此之外, Object类还提供了wait()notify()notifyAll()几个方法,通过这几个方法可以控制线程的暂停和运行。

克隆方法

Java还提供了一个protected修饰的clone()方法,该方法用于帮助其他对象来实现”自我克隆”,所谓”自我克隆”就是得到一个当前对象的副本,而且二者之间完全隔离。由于Object类提供的clone方法使用了protected修饰,因此该方法只能被子类重写或调用。

如何支持克隆

自定义类实现”克隆”的步骤如下。
自定义类实现Cloneable接口。Cloneable接口是一个标记性的接口,接口里没有定义任何方法,实现该接口的对象可以实现”自我克隆”。
自定义类实现自己的clone()方法。
实现clone()方法时通过super.clone();调用Object实现的clone方法来得到该对象的副本,并返回该副本。

Object类的clone方法只克隆值或地址

Object类提供的Clone机制只对对象的实例变量进行”简单复制”。

  • 如果对象实例变量的类型是基本类型,则直接复制值即可.
  • 如果对象实例变量的类型是引用类型,则只是复制这个引用变量中保存的地址.

这样被克隆对象的引用类型的实例变量,与克隆得到的对象的引用类型的实例变量指向的是内存中的同一个实例

只是浅克隆

所以,Object类的clone方法只是一种”浅克隆”。它只克隆该对象的所有成员变量值,不会对引用类型的成员变量值所引用的对象进行克隆

如果开发者需要对对象进行”深克隆”’则需要开发者自己进行”递归”克隆,保证所有引用类型的成员变量值所引用的对象都被复制了。

实例

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
class Address {
String detail;

public Address(String detail) {
this.detail = detail;
}
}

// 实现Cloneable接口
class User implements Cloneable {
int age;
Address address;

public User(int age) {
this.age = age;
address = new Address("花果山水帘洞");
}

// 通过调用super.clone()来实现clone()方法
public User clone() throws CloneNotSupportedException {
return (User) super.clone();
}
}

public class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
User u1 = new User(29);
// clone得到u1对象的副本。
User u2 = u1.clone();
// 不是相同的对象
System.out.println(u1 == u2);
// 只复制成员变量的值,不产生新对象,所以两个实例变量是同一个对象的引用
System.out.println(u1.address == u2.address);
}
}

运行结果:

1
2
false
true