????????Java 中的 Object
类是所有类的根类,它位于 java.lang
包中。所有其他类都直接或间接地继承自 Object
类。以下是关于 Object
类的一些详解:
/**
* native 方法,用于返回当前运行时对象的 Class 对象,使用了 final 关键字修饰,故不允许子类重写。
*/
public final native Class<?> getClass()
/**
* native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如 JDK 中的HashMap。
*/
public native int hashCode()
/**
* 用于比较 2 个对象的内存地址是否相等,String 类对该方法进行了重写以用于比较字符串的值是否相等。
*/
public boolean equals(Object obj)
/**
* native 方法,用于创建并返回当前对象的一份拷贝。
*/
protected native Object clone() throws CloneNotSupportedException
/**
* 返回类的名字实例的哈希码的 16 进制的字符串。建议 Object 所有的子类都重写这个方法。
*/
public String toString()
/**
* native 方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。
*/
public final native void notify()
/**
* native 方法,并且不能重写。跟 notify 一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。
*/
public final native void notifyAll()
/**
* native方法,并且不能重写。暂停线程的执行。注意:sleep 方法没有释放锁,而 wait 方法释放了锁 ,timeout 是等待时间。
*/
public final native void wait(long timeout) throws InterruptedException
/**
* 多了 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒。。
*/
public final void wait(long timeout, int nanos) throws InterruptedException
/**
* 跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念
*/
public final void wait() throws InterruptedException
/**
* 实例被垃圾回收器回收的时候触发的操作
*/
protected void finalize() throws Throwable { }
? ?getClass()
?方法返回对象的运行时类,即对象所属的类的 Class 对象。Class 对象提供了许多反射操作,如获取类名、获取字段和方法信息等。
返回类型:
getClass()
?方法返回的是?Class
?类型的对象,它是 Java 反射机制中的一个重要类。用途:
getClass()
?方法通常用于获取对象的运行时类型信息,包括类名、父类、接口等信息。通过?Class
?对象,可以进行许多反射操作,如获取字段和方法信息、创建新的对象实例等。示例:
下面是一个简单的示例,展示如何使用 getClass() 方法获取对象的类名:Object obj = new String("Hello, World!");
Class<?> cls = obj.getClass();
System.out.println(cls.getName());
// 输出:java.lang.String
上述代码中,我们首先创建了一个 String 类型的对象,并将其赋给一个 Object 类型的引用变量 obj。然后,通过 getClass() 方法获取 obj 对象的运行时类型信息,即 String 类型的 Class 对象。最后,通过 getName() 方法获取该类的名称并输出。????????需要注意的是,getClass()
方法返回的是对象的运行时类型,而不是编译时类型。这意味着,在多态的情况下,可能会返回不同的 Class
对象。如果需要获取编译时类型的信息,可以使用 instanceof
运算符。
? ?hashCode()
?方法返回对象的哈希码值,它用于在哈希表等数据结构中快速查找对象。默认情况下,hashCode()
?方法返回的是对象的内存地址的整数表示。如果重写了?equals()
?方法,通常也需要同时重写?hashCode()
?方法,以保持一致性。
返回类型:
hashCode()
?方法返回的是一个?int
?类型的哈希码值。用途:
HashMap
、HashSet
?等。它被用来快速定位对象存储的位置,以提高查找、插入和删除操作的性能。equals()
?方法返回?true
,那么它们的哈希码必须相等。因此,重写?equals()
?方法时通常也需要同时重写?hashCode()
?方法,以保持这个约定。默认实现:
Object
?类中的?hashCode()
?方法的默认实现是根据对象的内存地址计算得到的,即每个对象的哈希码都是唯一的。这在大多数情况下是不可接受的,因为我们希望具有相等属性的对象具有相同的哈希码。hashCode()
?方法,以便相等的对象具有相同的哈希码。通常,可以使用对象的字段来计算哈希码,确保相等的对象生成相同的哈希码。重写规则:
equals()
?方法,通常也需要同时重写?hashCode()
?方法。hashCode()
?方法时,应该保证满足以下规则:
equals()
?方法判断为相等,那么它们的哈希码必须相等。equals()
?方法可能返回?false
。下面是一个示例,展示如何重写 hashCode()
方法:
public class MyClass {
private int id;
private String name;
// 构造方法、getter 和 setter 省略
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
MyClass other = (MyClass) obj;
return id == other.id && Objects.equals(name, other.name);
}
}
????????在上述示例中,根据类的字段 id
和 name
来计算哈希码,并在 equals()
方法中比较这些字段的值。这样,具有相同 id
和 name
字段值的对象将具有相同的哈希码。
? ? equals()
?方法用于判断两个对象是否相等。默认情况下,equals()
?方法比较的是两个对象的引用是否相等,即它们是否指向同一个内存地址。可以通过重写?equals()
?方法来改变对象的相等比较方式。
方法签名:
Object
?类中,equals()
?方法的签名为?public boolean equals(Object obj)
。默认实现:
Object
?类中,equals()
?方法的默认实现是使用?==
?运算符来比较两个对象的引用是否相同,即判断对象的内存地址是否一致。equals()
?方法,它将和?==
?运算符具有相同的行为。这意味着只有当两个对象引用指向内存中的同一块区域时,equals()
?方法才会返回?true
。重写规则:
equals()
?方法。equals()
?方法时,应该保证满足以下几个约定:
true
。true
,那么 y.equals(x) 也应该返回?true
。true
?并且 y.equals(z) 也返回?true
,那么 x.equals(z) 也应该返回?true
。false
。示例:
下面是一个简单的示例,展示如何重写equals()
方法: public class MyClass {
private int id;
private String name;
// 构造方法、getter 和 setter 省略
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
MyClass other = (MyClass) obj;
return id == other.id && Objects.equals(name, other.name);
}
}
????????在上述示例中,根据类的字段 id
和 name
来判断两个对象是否相等。这样,具有相同 id
和 name
字段值的对象将被视为相等。
????????总之,equals()
方法用于判断两个对象是否相等,但默认情况下它比较的是对象的引用。因此,通常根据具体的业务需求来重写 equals()
方法,以便根据对象的内容来确定相等性。
? ?clone()
方法用于创建并返回当前对象的副本。这个方法执行的是浅拷贝(shallow copy),也就是复制对象的字段值。下面是关于 clone()
方法的详解:
使用方法:
????????要使用?clone()
?方法,首先需要确保被克隆的类实现了?Cloneable
?接口。该接口是一个标记接口,意味着它没有任何方法,只是用于标识能够进行克隆的类。然后,在要进行克隆的类中重写?clone()
?方法,并在方法内部调用父类的?clone()
?方法进行克隆。浅拷贝:
? ? ? ?默认情况下,clone()
?方法执行的是浅拷贝,即只复制对象的字段值。如果对象包含其他引用类型的字段,那么克隆后的新对象和原对象将共享这些引用类型的字段。如果需要实现深拷贝(deep copy),即复制对象及其引用类型字段的内容,可以在?clone()
?方法中手动处理这些引用类型字段的克隆。返回类型:
? ? ??clone()
?方法的返回类型是?Object
,因此在使用时需要进行类型转换。通常,将返回的?Object
?对象转换为克隆的具体类型。克隆方法的保护性质:
? ? ? ?clone()
?方法在?Object
?类中被声明为受保护的,这意味着只能在当前类及其子类中访问该方法。如果一个类没有实现?Cloneable
?接口或者尝试在其他类中调用该类的?clone()
?方法,将会抛出?CloneNotSupportedException
?异常。????????需要注意的是,虽然 clone()
方法提供了一种对象的复制方式,但它并不是推荐使用的方式。因为它存在一些问题,如对于可变对象的处理、构造函数的绕过以及性能开销等。更好的方式是使用拷贝构造函数或工厂方法来创建对象的副本,以实现更精确的控制和避免潜在的问题。
????toString()
方法是 Object
类中的一个方法,用于返回表示对象的字符串表示。
方法签名:
Object
?类中,toString()
?方法的签名为?public String toString()
。默认实现:
Object
?类中,toString()
?方法的默认实现返回一个包含类名和对象的哈希码的字符串,格式为?类名@哈希码
。toString()
?方法。重写规则:
toString()
?方法。toString()
?方法时,应该返回一个包含对象信息的字符串,以便能够描述对象的状态和属性。toString()
?方法的目的是为了提供可读性高、易于理解和调试的字符串表示。示例:
下面是一个示例,展示如何重写 toString()
方法:
public class MyClass {
private int id;
private String name;
// 构造方法、getter 和 setter 省略
@Override
public String toString() {
return "MyClass{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
? ? ? ? 在上述示例中,根据类的字段 id
和 name
来返回一个包含对象信息的字符串表示。通过重写 toString()
方法,我们可以得到类似于 "MyClass{id=1, name='John'}"
的字符串表示。
????????总之,toString()
方法用于返回对象的字符串表示,以便能够描述对象的状态和属性。默认情况下,它返回一个不太有用的字符串,因此通常需要根据具体的业务需求来重写 toString()
方法,以提供更有意义的字符串表示。
????notify()
方法是 Object
类中的一个方法,用于唤醒正在等待该对象的线程;notifyAll()
方法是 Object
类中的一个方法,用于唤醒正在等待该对象的所有线程。
方法签名:
Object
?类中,notify()
?方法的签名为?public final void notify()
。Object
?类中,notifyAll()
?方法的签名为?public final void notifyAll()
。使用条件:
notify()
?、notifyAll()
方法必须在同步块或同步方法中调用,并且只能由持有对象监视器(锁)的线程来调用。notify()、notifyAll()
?方法将会抛出?IllegalMonitorStateException
?异常。功能:
notify()/notifyAll()
? 方法时,它将唤醒正在等待该对象的线程中的 某一/全部 线程。被唤醒的线程将从等待状态转变为可运行状态,并且与其他线程一起竞争对象的监视器锁。notify()
?,notifyAll()
方法不会立即释放对象的监视器锁,而是在当前线程执行完同步代码块或同步方法后才会释放。示例:
下面是一个示例,展示如何使用 wait()
和 notify()
?、notifyAll()
方法进行线程间的通信:
public class MyClass {
public synchronized void doSomething() {
System.out.println("Thread A: Doing something...");
try {
wait(); // 线程 A 等待
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread A: Resumed!");
}
public synchronized void notifyThread() {
notify(); // 唤醒等待的线程
//notifyAll(); // 唤醒全部等待的线程
}
}
public class Main {
public static void main(String[] args) {
MyClass myObject = new MyClass();
Thread threadA = new Thread(() -> myObject.doSomething());
Thread threadB = new Thread(() -> myObject.notifyThread());
threadA.start(); // 启动线程 A
threadB.start(); // 启动线程 B
}
}
在上述示例中,线程 A 调用了 doSomething()
方法后进入等待状态,并通过 wait()
方法释放了对象的监视器锁。然后,线程 B 调用了 notifyThread()
方法,唤醒了线程 A,并让线程 A 重新获得对象的监视器锁并继续执行。
????????总之,notify()
?/ notifyAll()
方法用于唤醒正在等待该对象的线程中的 某一/全部 线程,让它从等待状态转变为可运行状态。使用 notify()、
notifyAll()
方法需要注意同步块或同步方法的使用,并且调用 notify()
、
notifyAll()
方法的线程必须持有对象的监视器锁。
wait()
方法:????wait()
方法是 Object
类中的一个方法,用于将当前线程置于等待状态,直到其他线程调用了该对象的 notify()
或 notifyAll()
方法来唤醒它。以下是关于 wait()
方法的详解:
方法签名:
Object
?类中,wait()
?方法有多个重载形式,其中最常用的签名为?public final void wait()
。使用条件:
wait()
?方法必须在同步块或同步方法中调用,并且只能由持有对象监视器(锁)的线程来调用。wait()
?方法将会抛出?IllegalMonitorStateException
?异常。功能:
wait()
?方法时,它会使当前线程进入等待状态,释放对象的监视器锁,直到其他线程调用了该对象的?notify()
?或?notifyAll()
?方法来唤醒它。示例:同notify()、notifyAll()方法事例
????????总之,wait()
方法用于将当前线程置于等待状态,直到其他线程调用了该对象的 notify()
或 notifyAll()
方法来唤醒它。使用 wait()
方法需要注意同步块或同步方法的使用,并且调用 wait()
方法的线程必须持有对象的监视器锁。
wait(long timeout)
方法:wait(long timeout)
方法是 Object
类中的一个重载方法,用于将当前线程置于等待状态,直到其他线程调用了该对象的 notify()
、notifyAll()
或指定的超时时间过去。以下是关于 wait(long timeout)
方法的详解:
方法签名:
Object
?类中,wait(long timeout)
?方法的签名为?public final void wait(long timeout) throws InterruptedException
。使用条件:
wait(long timeout)
?方法必须在同步块或同步方法中调用,并且只能由持有对象监视器(锁)的线程来调用。wait(long timeout)
?方法将会抛出?IllegalMonitorStateException
?异常。功能:
wait(long timeout)
?方法时,它会使当前线程进入等待状态,释放对象的监视器锁,并等待指定的时间。notify()
?或?notifyAll()
?方法唤醒,或者等待超时时间到达后自动恢复执行。notify()
?或?notifyAll()
?方法被调用,且等待时间还未到达,线程将被唤醒并继续执行。示例:
????????下面是一个示例,展示如何使用 wait(long timeout)
方法进行线程间的通信和超时等待:
public class MyClass {
public synchronized void doSomething() {
System.out.println("Thread A: Doing something...");
try {
wait(2000); // 线程 A 最多等待 2 秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread A: Resumed!");
}
public synchronized void notifyThread() {
notify(); // 唤醒等待的线程
}
}
public class Main {
public static void main(String[] args) {
MyClass myObject = new MyClass();
Thread threadA = new Thread(() -> myObject.doSomething());
Thread threadB = new Thread(() -> myObject.notifyThread());
threadA.start(); // 启动线程 A
threadB.start(); // 启动线程 B
}
}
????????在上述示例中,线程 A 调用了 doSomething()
方法后进入等待状态,并通过 wait(2000)
方法释放了对象的监视器锁,最多等待 2 秒。然后,线程 B 调用了 notifyThread()
方法,在等待时间到达前唤醒了线程 A,并让线程 A 重新获得对象的监视器锁并继续执行。
????????总之,wait(long timeout)
方法用于将当前线程置于等待状态,直到其他线程调用了该对象的 notify()
或 notifyAll()
方法,或者指定的超时时间到达。使用 wait(long timeout)
方法需要注意同步块或同步方法的使用,并且调用 wait(long timeout)
方法的线程必须持有对象的监视器锁。
wait(long timeout, int nanos)
方法是 Object
类中的一个重载方法,用于将当前线程置于等待状态,直到其他线程调用了该对象的 notify()
、notifyAll()
方法或指定的超时时间过去。该方法还允许设置纳秒级别的超时时间。以下是关于 wait(long timeout, int nanos)
方法的详解:
方法签名:
Object
?类中,wait(long timeout, int nanos)
?方法的签名为?public final void wait(long timeout, int nanos) throws InterruptedException
。使用条件:
wait(long timeout, int nanos)
?方法必须在同步块或同步方法中调用,并且只能由持有对象监视器(锁)的线程来调用。wait(long timeout, int nanos)
?方法将会抛出?IllegalMonitorStateException
?异常。功能:
wait(long timeout, int nanos)
?方法时,它会使当前线程进入等待状态,释放对象的监视器锁,并等待指定的时间(包括纳秒级别的时间)。notify()
?或?notifyAll()
?方法唤醒,或者等待超时时间到达后自动恢复执行。notify()
?或?notifyAll()
?方法被调用,且等待时间还未到达,线程将被唤醒并继续执行。示例:
下面是一个示例,展示如何使用 wait(long timeout, int nanos)
方法进行线程间的通信和纳秒级别的超时等待:
????????
public class MyClass {
public synchronized void doSomething() {
System.out.println("Thread A: Doing something...");
try {
wait(2_000, 500_000); // 线程 A 最多等待 2 秒 500 毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread A: Resumed!");
}
public synchronized void notifyThread() {
notify(); // 唤醒等待的线程
}
}
public class Main {
public static void main(String[] args) {
MyClass myObject = new MyClass();
Thread threadA = new Thread(() -> myObject.doSomething());
Thread threadB = new Thread(() -> myObject.notifyThread());
threadA.start(); // 启动线程 A
threadB.start(); // 启动线程 B
}
}
????????在上述示例中,线程 A 调用了 doSomething()
方法后进入等待状态,并通过 wait(2_000, 500_000)
方法释放了对象的监视器锁,最多等待 2 秒 500 毫秒。然后,线程 B 调用了 notifyThread()
方法,在等待时间到达前唤醒了线程 A,并让线程 A 重新获得对象的监视器锁并继续执行。
????????总之,wait(long timeout, int nanos)
方法用于将当前线程置于等待状态,直到其他线程调用了该对象的 notify()
或 notifyAll()
方法,或者指定的超时时间到达(包括纳秒级别的时间)。使用 wait(long timeout, int nanos)
方法需要注意同步块或同步方法的使用,并且调用 wait(long timeout, int nanos)
方法的线程必须持有对象的监视器锁。
finalize()
是 Object
类中的一个方法,用于在垃圾回收器对对象进行垃圾回收之前执行清理操作。以下是关于 finalize()
方法的详解:
方法签名:
Object
?类中,finalize()
?方法的签名为?protected void finalize() throws Throwable
。功能:
finalize()
?方法是 Java 垃圾回收机制的一部分,它用于在对象被垃圾回收之前进行一些必要的清理操作。finalize()
?方法。finalize()
?方法可以被子类重写,以实现特定的清理操作,例如关闭文件、释放资源等。执行时机:
finalize()
?方法的执行时机是不确定的,取决于垃圾回收器的调度和系统资源的可用性。finalize()
?方法的时间点是在垃圾回收器将对象标记为可回收,并在对象被实际回收之前。finalize()
?方法一定会被调用。注意事项:
finalize()
?方法应该小心使用,因为它的执行时间是不确定的,可能会影响应用程序的性能。try-finally
?语句块中关闭文件、释放资源等,而不是依赖于?finalize()
?方法。finalize()
?方法已被废弃。建议使用?try-with-resources
?或显式地调用资源释放方法来替代。示例:
下面是一个示例,展示了如何重写 finalize()
方法进行资源的清理操作:
public class MyClass {
private File file;
public MyClass() {
this.file = new File("example.txt");
}
@Override
protected void finalize() throws Throwable {
try {
// 清理操作,例如关闭文件
if (file != null) {
file.close();
}
} finally {
super.finalize();
}
}
}
在上述示例中,MyClass
类重写了 finalize()
方法,在方法中执行了关闭文件的操作。当对象被垃圾回收之前,垃圾回收器会调用 finalize()
方法来确保文件被关闭。
????????总之,finalize()
方法是 Object
类中的一个方法,用于在对象被垃圾回收之前执行清理操作。它应该小心使用,并且在实际编程中更推荐使用显式的资源释放方式替代。
更多消息资讯,请访问昂焱数据。