1.Object类

java.lang包是Java中最基础和最核心的包,它包含了Java编程中最基本的类,如String、Object、System等。这个包非常特殊,JVM会自动加载它,不需要使用import语句显式导入。

Object 是 Java 中所有类的根类:除了基本类型,任何引用类型都直接或间接继承 Object。所以一个 Object 引用可以指向任意对象。

java 复制代码
Object o1 = "hello";
Object o2 = Integer.valueOf(1);
Object o3 = new ArrayList<String>();

equals 方法

== 和equals的对比?有何区别?

==是比较运算符,既可以判断基本类型,又可以判断引用类型(引用类型中,变量值存储的是地址,其实是判断地址是否相等)。

equals 是object类中的方法,只能进行引用类型判断。

每个继承Object的子类都有可能重写Object的方法,比如String类重写了Object的equals方法:

java 复制代码
public boolean equals(Object anObject) {//接受一个string对象
    if (this == anObject) {//判断是否是同一个对象,其实比较的是变量中存储的地址是否一样
        return true;
    }
    if (anObject instanceof String) {//判断判断比较的对象是否是同一类型的数据
        String anotherString = (String)anObject; //强转
        int n = value.length;
        if (n == anotherString.value.length) {//比较两个字符串长度是否一致
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) { //比较两个字符串每一个字符是否相等
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

hashCode方法

返回一个对象的哈希码值。这种方法 支持哈希表的好处比如由 HashMap提供

  1. 调用同一对象,返回的hashcode一致,hashcode具有幂等性。

  2. 指向同一对象的hashcode一致,指向不同对象的hashcode不一致。

  3. hashcode的值是根据jvm内部地址转化来的

  4. 在集合中,hashcode有需要的话,也会重写。

toString方法

返回一个对象的字符串表示。一般来说, toString方法返回一个字符串,该字符串文本表示这个对象。结果应该是一个简洁但信息表示这是一个人容易阅读。建议所有子类重写这个方法。

类Object toString方法返回一个全类名(路径+类)+"@"+把 hashcode 转化为16进制 的字符串。

换句话说,该方法返回一个字符串的值等于:

复制代码
getClass().getName() + '@' + Integer.toHexString(hashCode())

一般重写toString就是为了打印对象的属性。

当直接输出一个对象时,toString方法会被默认调用。

finalize方法

当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。一般重写这个方法用于释放其他资源(开发中一般不会重写这个方法)。垃圾回收机制一般是由系统决定什么时候进行垃圾回收的,我们也可以使用System.gc();方法手动触发垃圾回收算法。

clone 方法

clone方法是Object的一个protected方法,这说明你的代码不能直接调用这个方法。

对于clone方法,如果对象中的所有数据域都是数值或其他基本类型,拷贝这些域没有任何问题。但是如果对象包含子对象的引用(比如string实例变量),拷贝域就会得到相同子对象的另一个引用,这样一来,原对象和克隆的对象仍然会共享一些信息。也就是说默认的克隆操作是"浅拷贝",并没有克隆对象中引用的其他对象。

对于每一个类,需要确定:

  1. 默认的clone方法是否满足要求;

  2. 是否可以在可变的子对象上调用clone来修补默认的clone方法;

  3. 是否不该使用clone。

实际上第3个选项是默认选项。如果选择第1项或第2项,类必须:

  1. 实现Cloneable接口;
  2. 重新定义clone方法,并指定public访问修饰符。

在这里,Cloneable接口的出现与接口的正常使用并没有关系。具体来说,它没有指定clone方法,这个方法是从Object类继承的。这个接口只是作为一个标记,指示类设计者了解克隆过程。对象对于克隆很"偏执",如果一个对象请求克隆,但没有实现这个接口,就会生成一个受查异常。也就是说如果执行深拷贝,那么就要实现Cloneable接口。

notify/notifyAll/wait

wait() / notify() / notifyAll() 是 Java 最基础的线程间等待/通知机制 ,定义在 java.lang.Object 上(不是 Thread),配合 synchronized 使用。

都是 final 的,不能被重写。

这三个方法都必须在 synchronized 块/方法中调用,并且锁对象就是调用 wait/notify 的那个对象:

java 复制代码
Object lock = new Object();

synchronized (lock) {
    lock.wait();     // 正确
}

synchronized (lock) {
    lock.notify();   // 正确
}

notify

如果有任何线程正在等待此对象,则会任意的选择其中一个被唤醒。被唤醒的线程从 WAITING 变为 BLOCKED,去竞争锁。

notifyAll

如果有任何线程正在等待此对象,则会唤醒所有等待此对象的线程。被唤醒的线程从 WAITING 变为 BLOCKED,然后依次竞争锁。

wait

每个对象都有一个监视器(monitor) ,wait 会把当前线程放入该对象的 wait set。前提是你必须先拥有这个对象的内置锁。

调用 wait() 时:

  1. 当前线程必须持有 obj 的锁
  2. 释放该对象锁;
  3. 线程进入 obj 的 wait set,状态变为 WAITING(带超时的变为 TIMED_WAITING);
  4. 等到被 notify/notifyAll 唤醒,或者超时,或者被 interrupt;
  5. 被唤醒后重新竞争 obj 的锁;
  6. 重新拿到锁后,从 wait() 之后继续执行。
java 复制代码
RUNNABLE
   │ 调用 wait()
   ▼
WAITING / TIMED_WAITING   (同时释放锁)
   │ 被 notify/notifyAll 唤醒 或 超时
   ▼
BLOCKED                    (等待重新获取锁)
   │ 获取到锁
   ▼
RUNNABLE
为什么必须用 while 而不是 if

一般我们都会这样写:

java 复制代码
while (queue.isEmpty()) {
    wait();  // 醒来后重新检查条件
}
int value = queue.poll();

主要原因是每次线程被notify唤醒,都是从wait()位置开始执行的。如果是if:

java 复制代码
if (queue.isEmpty()) { // 错误写法
    wait(); 
}
int value = queue.poll();

如果A从wait醒来后拿走队列之后一个值,处理业务后释放锁。B再从wait醒来,往下执行queue.poll(),会出现异常。

使用while,每次从wait醒来都会判断queue.isEmpty()

相关推荐
鸽鸽程序猿1 小时前
【项目】【在线判题系统】公共功能
java·spring boot·maven
一只笨菜鸟1 小时前
IDEA如何让多个项目同时显示
java·ide·intellij-idea
G018_star sky♬1 小时前
java中的字符串常见方法
java·开发语言
.Bryce.2 小时前
你了解 Blackboard(黑板系统)吗?听说过基于黑板系统实现的智能体吗?
java·网络·gpt·php·agent·codex·黑板系统
猿究院_夏燊9 小时前
Spring Bean 生命周期
java·后端·spring
Wang's Blog10 小时前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
信誓旦旦的程序猿10 小时前
【Python量化实战宝典 #08】可转债与债券接口手册:转股价·溢价率·纯债价值(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
砚底藏山河10 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
Jlzn888810 小时前
华东电芯分选通道数怎么配才不堵线
java·人工智能·架构·自动化·制造