Java中Object和Class类的使用
立即解锁
发布时间: 2025-08-18 00:27:49 阅读量: 2 订阅数: 19 

### Java 中 Object 和 Class 类的使用
在 Java 面向对象编程中,`Object` 类和 `Class` 类是非常重要的两个类。`Object` 类是所有类的基类,而 `Class` 类则用于获取对象类型的信息。虽然这些内容有些技术化,很多 Java 程序员可能多年不理解或使用它们也能正常工作,但了解这些知识有助于解释 Java 中一些不符合预期的现象,还可能在遇到难题时帮助我们找到解决方案。
#### 1. 万物之母:Object 类
在 Java 里,每个类最终都会继承 `Object` 类,该类为所有 Java 对象提供了一组方法。
##### 1.1 每个对象都是 Object 类型
任何没有 `extends` 子句的类都会隐式继承 `Object` 类,所以我们无需编写 `public class Product extends Object` 这样的代码。若子类的 `extends` 子句指定了非 `Object` 的父类,该类依然会继承 `Object` 类,因为继承层次最终会到达一个没有 `extends` 子句的父类,这个父类继承 `Object` 类并将其传递给所有子类。例如:
```java
public class Manager extends SalariedEmployee...
public class SalariedEmployee extends Employee...
public class Employee extends Person...
public class Person...
```
`Manager` 类间接继承 `Object` 类,因为它继承 `SalariedEmployee`,`SalariedEmployee` 继承 `Employee`,`Employee` 继承 `Person`,而 `Person` 继承 `Object` 类。在 Java 中,创建不继承 `Object` 类的类是不可能的。
##### 1.2 将 Object 作为类型
如果我们不知道或不关心变量引用的对象类型,可以将其类型指定为 `Object`。例如:
```java
Object emp = new Employee();
```
但这样做后,由于编译器不知道 `emp` 是 `Employee` 类型,所以一些操作无法进行。比如 `Employee` 类有 `setLastName` 方法,以下代码无法编译:
```java
Object emp = new Employee();
emp.setLastName("Smith"); // error: won't compile
```
不过,我们可以将对象强制转换为 `Employee` 类型:
```java
Object emp = new Employee();
((Employee)emp).setLastName("Smith"); // this works
```
但这样做意义不大,不如一开始就将 `emp` 声明为 `Employee` 类型。不过,在某些情况下,将变量、参数或返回类型声明为 `Object` 是有意义的。例如,Java API 中的 `ArrayList` 类有一个 `add` 方法,其参数类型为 `Object`,这使得我们可以使用 `ArrayList` 类创建任何类型对象的集合。
##### 1.3 Object 类的方法
以下是 `Object` 类的所有方法:
| 方法 | 作用 |
| --- | --- |
| `protected Object clone()` | 返回该对象的一个副本 |
| `boolean equals(Object obj)` | 指示该对象是否等于 `obj` 对象 |
| `protected void finalize()` | 当对象被垃圾回收器销毁时调用 |
| `Class getClass()` | 返回一个表示该对象运行时类的 `Class` 对象 |
| `int hashCode()` | 返回该对象的哈希码 |
| `void notify()` | 用于线程应用程序,唤醒等待该对象的一个线程 |
| `void notifyAll()` | 用于线程应用程序,唤醒等待该对象的所有线程 |
| `String toString()` | 返回该对象的字符串表示形式 |
| `void wait()` | 使该对象的线程等待,直到另一个线程调用 `notify` 或 `notifyAll` |
| `void wait(Long timeout)` | `wait` 方法的变体 |
| `void wait(Long timeout, int nanos)` | `wait` 方法的另一种变体 |
其中,`notify`、`notifyAll` 和三个 `wait` 方法与线程相关。下面是其余六个方法的介绍:
- **`clone`**:常用于复制对象,在自定义类中重写此方法很常见。
- **`equals`**:常用于比较对象,任何表示可比较对象的类都应重写此方法。
- **`finalize`**:当垃圾回收器意识到对象不再使用并可丢弃时调用,其目的是让对象在被丢弃前进行清理工作,但由于 Java 垃圾回收器的工作方式,不能保证该方法一定会被调用,因此不常用。
- **`getClass`**:有时会与 `Class` 类一起使用。
- **`hashCode`**:每个 Java 对象都有哈希码,在使用哈希表时该方法比较重要。
- **`toString`**:Java 中最常用的方法之一。
需要注意的是,基本数据类型(如 `int` 和 `double`)不是对象,它们不继承 `Object` 类,也无法访问上述方法。例如:
```java
int x = 50;
String s = x.toString(); // error: won't compile
```
若要将 `int` 转换为字符串,可以使用包装类,如 `Integer`:
```java
String s = new Integer(x).toString(); // OK
```
或者使用包装类的静态 `toString` 方法:
```java
String s = Integer.toString(x);
```
也可以使用编译器的快捷方式:
```java
String s = "" + x;
```
#### 2. toString 方法
`toString` 方法返回对象的字符串表示形式,默认情况下,它返回对象类名加上其哈希码。
##### 2.1 使用 toString 方法
以下是一个简单的程序,展示了 `toString` 方法的使用:
```java
public class TestToString
{
public static void main(String[] args)
{
Employee emp = new Employee("Martinez",
"Anthony");
System.out.println(emp.toString());
}
}
class Employee
{
private String lastName;
private String firstName;
public Employee(String lastName, String firstName)
{
this.lastName = lastName;
this.firstName = firstName;
}
}
```
运行该程序,控制台会输出类似 `Employee@82ba41` 的内容,其中哈希码在不同系统上可能不同。实际上,在这个例子中,显式调用 `toString` 方法并非必要,因为 `println` 方法会自动调用传入对象的 `toString` 方法,我们可以直接写 `System.out.println(emp)`。
##### 2.2 重写 toString 方法
默认的 `toString` 方法在大多数情况下用处不大。例如,仅通过查看哈希码,我们无法了解 `Employee` 对象的实际信息。若能让 `toString` 方法返回对象的实际数据,如员工姓名,会更有意义。为此,我们需要在类中重写 `toString` 方法。在 Jav
0
0
复制全文
相关推荐










