Java Object类学习:
Object类是所有Java类的根类,处于类继承层次的最顶端,该类的大多数方法都是native方法。
1. clone方法:
(1) 如果在该方法直接返回super.clone()的对象, 那么该方法实现对象的“浅拷贝”,如果被拷贝的类中有引用类型的字段,调用此方法后被拷贝的对 象和源对象的引用字段指向同一个对象,任意对象对该引用对象的修改都会表现在两个对象上。
如果要想使两个对象彼此分离,应该对super.clone()返回的对象的引用字段做一定的修改,以实现深拷贝。
(2) 重写clone方法的类必须实现Cloneable接口,否则在调用clone方法时会抛出CloneNotSupportedException异常,由于Object类没有实现Cloneable接口,所以重写clone方法的类必须手动实现。
(3) Java的浅拷贝类似于C++的默认拷贝构造函数,不能正确处理引用/指针,如要实现深拷贝,必须重写引用/指针指向对象的控制对象复制的函数(clone/拷贝构造函数)。
package com.lang;
class Test01 implements Cloneable {
int i = 10;
String s = new String("fre");
@Override
public Test01 clone() throws CloneNotSupportedException {
return (Test01) super.clone();
}
}
class Test02 implements Cloneable {
Test01 test01 = new Test01();
int num = 20;
/*
@Override
public Test02 clone() throws CloneNotSupportedException {
return (Test02) super.clone();
}
*/
@Override
public Test02 clone() throws CloneNotSupportedException {
Test02 obj = (Test02) super.clone();
obj.test01 = obj.test01.clone();
return obj;
}
}
public class CloneMain {
public static void main(String[] args) {
Test02 test1 = new Test02();
Test02 test2 = null;
try {
test2 = test1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
2. toString方法
(1) toString方法返回对象的字符串表示,默认返回
getClass().getName() + '@' + Integer.toHexString(hashCode())
为了使该方法返回更有意义的字符串,每个类都应该重写该方法。
3. wait方法
wait方法会释放对某个对象的锁,当某个线程调用wait方法时,该线程会被加入该对象的等待集合中,所以只会释放该线程在该对象上的锁,该线程在其他对象上的锁则不会被释放。
在没有被通知、中断或超时的情况下,线程还可以唤醒一个所谓的虚假唤醒 (spurious wakeup)。虽然这种情况在实践中很少发生,但是应用程序必须通过以下方式防止其发生,即对应该导致该线程被提醒的条件进行测试,如果不满足该条件,则继续等待。换句话说,等待应总是发生在循环中,如下面的示例:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
// Perform action appropriate to condition
}
}
4. notify/notifyAll方法
唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
5. finalize方法
当垃圾回收器确定不存在对该对象的更多引用时,由垃圾回收器调用此方法,垃圾回收器作为后台线程运行,Java 虚拟机最多只调用一次 finalize 方法。
6. equals方法
指示某个对象是否与此对象“相等"。
Object的equals(object) 实现逻辑为:当且仅当两个引用指向同一个对象时才会返回true。
注意: 当该方法被重写时,通常有必要同步重写hashCode方法以维护关于hashCode的协定。
7. hashCode方法
返回对象的hash码,实现此方法的目的是为了提高hash表的性能。
注意:(1) 如果两个对象调用equals相同,那么这两个对象的hashCode一定相同。
(2) 如果两个对象调用equals不相同,这两个对象的hashCode不一定不相同(存在hash
冲突)。
8. getClass方法
返回对象的运行时类。返回的对象是类的static synchronized方法锁定的对象。该方法的返回值实际类型为Class<? extends |X|>,|X|为调用该方法的对象的静态类型。
注意: 之所以返回Class<? extends |X|>,是由于Java多态的存在,存在将基类的引用绑定到子类的对象,所以|X|可以为基类本身,也可以为该基类的子对象,这正是<? extends |X|>的语义。
Object类是所有Java类的根类,处于类继承层次的最顶端,该类的大多数方法都是native方法。
1. clone方法:
(1) 如果在该方法直接返回super.clone()的对象, 那么该方法实现对象的“浅拷贝”,如果被拷贝的类中有引用类型的字段,调用此方法后被拷贝的对 象和源对象的引用字段指向同一个对象,任意对象对该引用对象的修改都会表现在两个对象上。
如果要想使两个对象彼此分离,应该对super.clone()返回的对象的引用字段做一定的修改,以实现深拷贝。
(2) 重写clone方法的类必须实现Cloneable接口,否则在调用clone方法时会抛出CloneNotSupportedException异常,由于Object类没有实现Cloneable接口,所以重写clone方法的类必须手动实现。
(3) Java的浅拷贝类似于C++的默认拷贝构造函数,不能正确处理引用/指针,如要实现深拷贝,必须重写引用/指针指向对象的控制对象复制的函数(clone/拷贝构造函数)。
package com.lang;
class Test01 implements Cloneable {
int i = 10;
String s = new String("fre");
@Override
public Test01 clone() throws CloneNotSupportedException {
return (Test01) super.clone();
}
}
class Test02 implements Cloneable {
Test01 test01 = new Test01();
int num = 20;
/*
@Override
public Test02 clone() throws CloneNotSupportedException {
return (Test02) super.clone();
}
*/
@Override
public Test02 clone() throws CloneNotSupportedException {
Test02 obj = (Test02) super.clone();
obj.test01 = obj.test01.clone();
return obj;
}
}
public class CloneMain {
public static void main(String[] args) {
Test02 test1 = new Test02();
Test02 test2 = null;
try {
test2 = test1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
2. toString方法
(1) toString方法返回对象的字符串表示,默认返回
getClass().getName() + '@' + Integer.toHexString(hashCode())
为了使该方法返回更有意义的字符串,每个类都应该重写该方法。
3. wait方法
wait方法会释放对某个对象的锁,当某个线程调用wait方法时,该线程会被加入该对象的等待集合中,所以只会释放该线程在该对象上的锁,该线程在其他对象上的锁则不会被释放。
在没有被通知、中断或超时的情况下,线程还可以唤醒一个所谓的虚假唤醒 (spurious wakeup)。虽然这种情况在实践中很少发生,但是应用程序必须通过以下方式防止其发生,即对应该导致该线程被提醒的条件进行测试,如果不满足该条件,则继续等待。换句话说,等待应总是发生在循环中,如下面的示例:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
// Perform action appropriate to condition
}
}
4. notify/notifyAll方法
唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait 方法,在对象的监视器上等待。
5. finalize方法
当垃圾回收器确定不存在对该对象的更多引用时,由垃圾回收器调用此方法,垃圾回收器作为后台线程运行,Java 虚拟机最多只调用一次 finalize 方法。
6. equals方法
指示某个对象是否与此对象“相等"。
Object的equals(object) 实现逻辑为:当且仅当两个引用指向同一个对象时才会返回true。
注意: 当该方法被重写时,通常有必要同步重写hashCode方法以维护关于hashCode的协定。
7. hashCode方法
返回对象的hash码,实现此方法的目的是为了提高hash表的性能。
注意:(1) 如果两个对象调用equals相同,那么这两个对象的hashCode一定相同。
(2) 如果两个对象调用equals不相同,这两个对象的hashCode不一定不相同(存在hash
冲突)。
8. getClass方法
返回对象的运行时类。返回的对象是类的static synchronized方法锁定的对象。该方法的返回值实际类型为Class<? extends |X|>,|X|为调用该方法的对象的静态类型。
注意: 之所以返回Class<? extends |X|>,是由于Java多态的存在,存在将基类的引用绑定到子类的对象,所以|X|可以为基类本身,也可以为该基类的子对象,这正是<? extends |X|>的语义。