一、Object类
Java中的Object类,有什么作用。
对于Object类中的方法,按照功能进行划分,简洁告诉我它们的核心作用
1) 类型信息和文本表示(调试/日志)
getClass():返回运行时真实类型(反射入口,知道“这个对象到底是什么类”);
toString():把对象转成可读字符串(默认是 类名@哈希,通常会重写成更有意义的信息)。
2) 相等性与哈希
equals(Object obj):判断“逻辑上是否相等”(默认实现是 ==,也就是同一对象)。
hashCode():返回哈希值(配合 equals 用于 HashMap/HashSet 等散列结构)。
3) 多线程同步:等待/通知(必须在 synchronized 里用)
wait() / wait(long) / wait(long,int):
让当前线程在该对象的“监视器锁”上等待,直到被唤醒或超时。
notify():随机唤醒一个正在等待该对象锁的线程。
notifyAll():唤醒所有正在等待该对象锁的线程。
这组方法体现了:每个对象天生都能当作“锁/条件队列”使用(对象自带 monitor)
4)好像没有提到clone(),这个方法不重要or 不常用吗?
确实一般不用;clone() 核心作用:
protected Object clone():复制当前对象,
默认是“浅拷贝”(把字段值按位复制;引用字段只复制引用,不会把引用指向的对象也复制一份)。
二、 浅拷贝
1.“浅拷贝 = 逐字段复制(field-by-field copy)
基本类型,是复制值;
引用类型:复制“引用值”(地址/指针意义上的值),Integer,String也不例外
2.数组/集合是最常见坑
像 int[]、Object[]、ArrayList、自定义对象字段——浅拷贝后,
两边会指向同一个数组/集合/子对象,改一边等于改另一边。
3.浅拷贝不一定“错误”,问题在于“可变共享”
只要共享的是不可变对象,或你明确想共享(比如缓存/只读数据),浅拷贝完全没问题;真正危险的是共享了可变对象还被两边修改
我想看clone()源码,发现它是native,看不到;
4. 外壳是新的,内部引用字段是共用的
User u2 = u1.clone();
u1 == u2
u2指向新建的对象,u1和u2不是同一个对象
import java.util.*;
public class ShallowCopyDemo1 {
public static void main(String[] args) throws Exception {
User u1 = new User("A");
u1.tags.add("java");
User u2 = u1.clone();
u2.tags.add("spring");
System.out.println("u1.tags = " + u1.tags);
System.out.println("u2.tags = " + u2.tags);
System.out.println("same list? " + (u1.tags == u2.tags));
}
static class User implements Cloneable {
String name;
List<String> tags = new ArrayList<>();
User(String name) { this.name = name; }
@Override
public User clone() throws CloneNotSupportedException {
return (User) super.clone();
}
}
}
三、深拷贝
深拷贝:新对象 + 内部引用也指向“新拷贝”的对象(尽量不共享可变状态)
深拷贝和浅拷贝在重写时的区别:
我认为:
前者只是简单调用,不在方法体中补充内容,eg:
@Override
public User clone() throws CloneNotSupportedException {
return (User) super.clone();
}
后者需要
@Override再把可变引用字段复制一份
public User clone() throws CloneNotSupportedException {
User copy = (User) super.clone();
copy.tags = new ArrayList<>(this.tags);
return copy;
}
简单来说:
浅拷贝:只 super.clone()
深拷贝:super.clone() + 把所有“可变引用字段”递归复制到不共享为止
补充:
像 String/Integer 这种不可变对象,就算共享引用也安全,所以深拷贝通常只需要处理可变引用字段(数组、集合、Map、自定义可变子对象等)