Object 类
toString
默认实现
java
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}getClass().getName():返回对象的类名(包括包名)。hashCode():返回对象的哈希值(整数)。Integer.toHexString(hashCode()):把哈希值转成十六进制。- 默认输出示例:
java
com.example.MyClass@1a2b3c4重写
为了打印更有意义的信息,通常会在自定义类中重写 toString():
java
class Person {
String name;
int age;
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}打印对象时:System.out.println(obj) 会自动调用 obj.toString()。
java
Person p = new Person();
p.name = "Alice";
p.age = 25;
System.out.println(p); // 自动调用 toString()java
Person{name='Alice', age=25}equals
用来判断两个对象是否“相等”
默认实现
java
public boolean equals(Object obj) {
return (this == obj);
}默认实现其实就是用 == 判断是否是同一个对象引用。
java
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // false,引用不同
System.out.println(a.equals(b)); // false,默认 Object 的 equals 也是引用比较字符串只能使用
equals比较是否相等,String已重写了equals方法
重写
默认的 equals() 只比较引用,对于我们自定义的类,大多数时候我们想比较对象的 内容/属性 是否相等,而不是引用。
java
package org.example.boot.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Date {
private int year;
private int month;
private int day;
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if (obj instanceof Date) {
Date date = (Date) obj;
if (this.year == date.year && this.month == date.month && this.day == date.day) {
return true;
}
}
return false;
}
}clone
clone() 是 Object 类中的一个方法,用于复制当前对象,生成一个新的对象。它属于 Java 提供的一种对象拷贝机制。
默认实现
在 Object 类中的定义:
java
protected native Object clone() throws CloneNotSupportedException;protected:默认只能在本类或子类中使用native:底层由 JVM实现返回值:
Object可能抛出
CloneNotSupportedException
Object的clone为什么不设计成public?
Java 不希望所有对象默认都可以被克隆。任何对象都可以随意复制,这会带来很多问题。因此设置为protected将控制权交给类作者决定对象是否可以被克隆
浅拷贝
如果一个类想要使用 clone(),必须:
- 实现
Cloneable接口 - 重写 clone() 方法,并提高访问权限(原有权限是protected,一般改为 public)
Cloneable 是一个 标记接口,没有方法,只是告诉 JVM:这个类允许被 clone。如果不实现 Cloneable,调用 clone() 会抛异常。
java
class Person implements Cloneable {
String name;
int age;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}java
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person();
p1.name = "Tom";
p1.age = 20;
Person p2 = (Person) p1.clone();
System.out.println(p1 == p2); // false
System.out.println(p1.name); // Tom
System.out.println(p2.name); // Tom
}
}深拷贝
clone() 默认是 浅拷贝,深拷贝需要 手动 clone 引用对象。
java
package org.example.boot.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Address implements Cloneable{
private String city;
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}java
package org.example.boot.bean;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Person implements Cloneable{
private String name;
private int age;
private Address address;
@Override
public Object clone() throws CloneNotSupportedException {
Person person = (Person) super.clone();
person.address = (Address) address.clone();
return person;
}
}java
import lombok.val;
import org.example.boot.bean.Address;
import org.example.boot.bean.Person;
import org.junit.jupiter.api.Test;
public class PersonTest {
@Test
void test1() throws CloneNotSupportedException {
Address address = new Address("上海");
Person p1 = new Person("lai",18, address);
System.out.println(p1);
Person p2 = (Person) p1.clone();
address.setCity("三明");
System.out.println(p1);
System.out.println(p2);
}
}缺陷
企业中 不推荐使用 clone,原因:
Cloneable设计不好(标记接口)clone()返回Object需要强转- 容易出现 浅拷贝问题
- 需要处理异常
通常使用BeanUtils:
java
BeanUtils.copyProperties(p1, p2);hashCode
java
public native int hashCode();默认 hashCode ≈ 对象的“内存标识”
同一个对象,多次调用 hashCode 的结果是一样的,因为引用没有发生变化
