跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

详解Java中Object 类的使用

目录Object 类提供的方法方法实例clone() 方法equals() 方法finalize() 方法getClass() 方法hashCode() 方法wait() 方法notify() 与 notifyAll() 方法toString() 方法Java的Object 类是所有类的父类,也就是说 Java 的所有类都继承了 Object,子类可以使用 Object 的所有方法。Object 类位于 java.lang 包中,编译时会自动导入,我们创建一个类时,如果没有明确继承一个父类,那么它就会自动继承 Object,成为 Object 的子类。

Object 类可以显式继承,也可以隐式继承,以下两种方式是一样的:// 显式继承:public class Runoob extends Object{ }// 隐式继承:public class Runoob { }Object 类提供的方法方法描述Object()构造一个新对象protected Object clone()创建并返回一个对象的拷贝boolean equals(Object obj)比较两个对象是否相等protected void finalize()当 GC (垃圾回收器)确定不存在对该对象的有更多引用时,由对象的垃圾回收器调用此方法Class getClass()获取对象的运行时对象的类int hashCode()获取对象的 hash 值void notify()唤醒在该对象上等待的某个线程void notifyAll()唤醒在该对象上等待的所有线程String toString()返回对象的字符串表示形式void wait()让当前线程进入等待状态。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法void wait(long timeout)让当前线程处于等待(阻塞)状态,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过参数设置的timeout超时时间void wait(long timeout, int nanos)与 wait(long timeout) 方法类似,多了一个 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒方法实例clone() 方法protected native Object clone() throws CloneNotSupportedException;

描述:

用于创建并返回一个对象的拷贝。clone 方法是浅拷贝,对象内属性引用的对象只会拷贝引用地址,而不会将引用的对象重新分配内存。

参数:

无

返回值:

返回一个对象的拷贝。

注意:

由于 Object 本身没有实现 Cloneable 接口,所以不重写 clone 方法并且进行调用的话会发生 CloneNotSupportedException 异常。

public class Test implements Cloneable {// 声明变量String name;int likes;// 属性引用的对象JueJin jueJin;Test() {this.jueJin = new JueJin();}public static void main(String args[]) {// 创建对象Test obj1 = new Test();// 初始化变量obj1.name = "Runoob";obj1.likes = 111;obj1.jueJin.name = "掘金";// 打印输出System.out.println("obj1 的 name = " + obj1.name); // Runoob System.out.println("obj1 的 likes = " + obj1.likes); // 111 System.out.println("obj1 的 jueJin 的 name = " + obj1.jueJin.name); //掘金try {// 创建 obj1 的拷贝Test obj2 = (Test) obj1.clone();obj2.name = "JueJin";obj2.likes = 222;obj2.jueJin.name = "稀土掘金";// 使用 obj2 输出变量System.out.println();System.out.println("obj2 的 name = " + obj2.name); // JueJin System.out.println("obj2 的 likes = " + obj2.likes); // 222 System.out.println("obj2 的 jueJin 的 name = " + obj2.jueJin.name); //稀土掘金System.out.println();System.out.println("浅拷贝的问题");System.out.println("obj1 的 name = " + obj1.name); // Runoob System.out.println("obj1 的 likes = " + obj1.likes); // 111 System.out.println("obj1 的 jueJin 的 name = " + obj1.jueJin.name); //稀土掘金} catch (Exception e) {System.out.println(e);}}}class JueJin {public String name;}// 以上程序执行结果为:// obj1 的 name = Runoob// obj1 的 likes = 111// obj1 的 jueJin 的 name = 掘金// obj2 的 name = JueJin// obj2 的 likes = 222// obj2 的 jueJin 的 name = 稀土掘金// 浅拷贝的问题// obj1 的 name = Runoob// obj1 的 likes = 111// obj1 的 jueJin 的 name = 稀土掘金

解析:

由于浅拷贝对对象内属性引用的对象只会拷贝引用地址,所以 obj1 与 obj2 的 jueJin 属性引用的对象指向同一内存地址,所以在 obj2 修改 jueJin 的 name 属性后,obj1 的 jueJin 的 name 属性也发生了变化。

equals() 方法public boolean equals(Object obj)

描述:

用于比较两个对象是否相等。比较两个对象时,是通过判断两个对象引用指向的是同一个对象,即比较 2 个对象的内存地址是否相等。

参数:

obj -- 要比较的对象。

返回值:

如果两个对象相等返回 true,否则返回 false。

注意:

不同的类重写了 equals() 方法,导致equals() 方法的行为有所不同。但如果子类重写了 equals() 方法,就需要重写 hashCode() 方法,比如 String 类就重写了 equals() 方法,同时也重写了 hashCode() 方法。

public class Test implements Cloneable {public static void main(String args[]) {// 创建两个对象Object obj1 = new Object();Object obj2 = new Object();// 判断 obj1 与 obj2 是否相等// 不同对象,内存地址不同,不相等,返回 false System.out.println(obj1.equals(obj2)); // false// obj1 赋值给 obj3// 对象引用,内存地址相同,相等,返回 true Object obj3 = obj1;System.out.println(obj1.equals(obj3)); // true}}// 以上程序执行结果为:// false// truefinalize() 方法protected void finalize() throws Throwable { }

描述:

用于实例被垃圾回收器回收的时触发的操作。当 GC (垃圾回收器) 确定不存在对该对象的有更多引用时,对象的垃圾回收器就会调用这个方法。

参数:

无

返回值:

无public class Test {public static void main(String args[]) {JunJin junJin = new JunJin();junJin = null;System.gc();}}class JunJin {@Override protected void finalize() throws Throwable {super.finalize();System.out.println("对象被回收了");}}// 以上程序执行结果为:// 对象被回收了getClass() 方法public final native Class getClass();

描述:

用于获取对象的运行时对象的类。

参数:

无

返回值:

返回对象的类。

public class Test {public static void main(String args[]) {// getClass() with Object Object obj1 = new Object();System.out.println("obj1 的类为: " + obj1.getClass());// getClass() with String String obj2 = new String();System.out.println("obj2 的类为: " + obj2.getClass());// getClass() with ArrayList ArrayList obj3 = new ArrayList<>();System.out.println("obj3 的类为: " + obj3.getClass());}}// 以上程序执行结果为:// obj1 的类为: class java.lang.Object// obj2 的类为: class java.lang.String// obj3 的类为: class java.util.ArrayListhashCode() 方法public native int hashCode();

描述:

用于获取对象的 hash 值。

参数:

无

返回值:

返回对象哈希值,是一个整数,表示在哈希表中的位置。

public class Test {public static void main(String args[]) {// Object 使用 hashCode() Object obj1 = new Object();// obj1 赋值给 obj2 Object obj2 = obj1;// 判断两个对象是否相等System.out.println(obj1.equals(obj2)); // true// 获取 obj1 与 obj2 的哈希值System.out.println("对象相等则hashCode一定相等");System.out.println(obj1.hashCode()); // 225534817 System.out.println(obj2.hashCode()); // 225534817}}// 以上程序执行结果为:// true// 对象相等则hashCode一定相等// 692404036// 692404036wait() 方法// 该方法有以下几种语法格式:public final void wait() throws InterruptedException public final native void wait(long timeout) throws InterruptedException public final void wait(long timeout, int nanos) throws InterruptedException

描述:

让当前线程进入等待状态。

参数:

timeout -- 等待超时时间(以毫秒为单位)。如果 timeout 参数为 0,则不会超时,会一直进行等待,类似于 wait() 方法。如果阻塞的时间超过该参数时间,会唤醒线程。

nanos -- 额外时间(以纳秒为单位,范围是 0-999999)。如果设置该时间,超时的时间还需要加上 nanos 纳秒。

返回值:

无

注意:

当前线程必须是此对象的监视器所有者,否则还是会发生 IllegalMonitorStateException 异常。

如果当前线程在等待之前或在等待时被任何线程中断,则会抛出 InterruptedException 异常。

如果传递的参数不合法,则会抛出 IllegalArgumentException 异常。

notify() 与 notifyAll() 方法public final native void notify();

描述:

用于唤醒一个在此对象监视器上等待的线程。如果所有的线程都在此对象上等待,那么只会选择一个线程,选择是任意性的,并在对实现做出决定时发生。

参数:

无

返回值:

无public final native void notifyAll();

描述:

用于唤醒在该对象上等待的所有线程。notifyAll() 方法跟 notify() 方法的区别在于 notifyAll() 方法唤醒在此对象监视器上等待的所有线程,notify() 方法是一个线程。

参数:

无

返回值:

无public class Test {// 声明一个同步列表private List synchedList;/*** 构造方法*/ public Test() {// 创建一个同步列表synchedList = Collections.synchronizedList(new LinkedList());}/*** 删除列表中的元素* @return 删除的元素* @throws InterruptedException*/ public String removeElement() throws InterruptedException {synchronized (synchedList) {// 列表为空就等待while (synchedList.isEmpty()) {System.out.println("列表是空的...");System.out.println("线程 " + Thread.currentThread().getName() + " 将开始等待...");synchedList.wait();System.out.println("线程 " + Thread.currentThread().getName() + " 等待结束!");}// 删除元素String element = (String) synchedList.remove(0);// 返回删除的元素return element;}}/*** 添加元素到列表* @param element 要添加的元素*/ public void addElement(String element) {synchronized (synchedList) {// 添加一个元素,并通知元素已存在synchedList.add(element);System.out.println("添加了新元素:'" + element + "'");synchedList.notify();System.out.println("notify 已调用,唤醒 synchedList 上等待的任意一个线程!");//synchedList.notifyAll();//System.out.println("notifyAll 已调用,唤醒 synchedList 上等待的所有线程!");}System.out.println("添加元素完成...");}/*** main 函数* @param args*/ public static void main(String args[]) {final Test demo = new Test();Runnable runA = new Runnable() {public void run() {try {// 删除 synchedList 中的一个元素并输出String item = demo.removeElement();System.out.println("删除了元素 " + item);} catch (InterruptedException ix) {System.out.println("中断的异常!");} catch (Exception x) {System.out.println("Exception thrown.");}}};Runnable runB = new Runnable() {// 执行添加元素操作,并开始循环public void run() {demo.addElement("Hello!");}};try {// 创建线程 threadA1 并开始执行Thread threadA1 = new Thread(runA, "Google");threadA1.start();// 当前执行 main 方法的线程休眠Thread.sleep(500);// 创建线程 threadA2 并开始执行Thread threadA2 = new Thread(runA, "Runoob");threadA2.start();// 当前执行 main 方法的线程休眠Thread.sleep(500);// 创建线程 threadB 并开始执行Thread threadB = new Thread(runB, "Taobao");threadB.start();// 当前执行 main 方法的线程休眠Thread.sleep(1000);// 中断 threadA1 线程threadA1.interrupt();// 中断 threadA2 线程threadA2.interrupt();} catch (InterruptedException x) {System.out.println(x);}}}使用 notify() 方法唤醒线程时,可以看到 Google 线程的等待被唤醒了,但 Runoob 线程的等待最终没有被唤醒,输出如下:列表是空的...

线程 Google 将开始等待...

列表是空的...

线程 Runoob 将开始等待...

添加了新元素:'Hello!'

notify 已调用,唤醒 synchedList 上等待的任意一个线程!

添加元素完成...

线程 Google 等待结束!

删除了元素 Hello!

中断的异常!使用 notifyAll() 方法唤醒线程时,可以看到 Runoob 与 Google 线程的等待都被唤醒了,但 Runoob 线程唤醒后将集合中的元素删除了,所以集合再次变为空的,Google 就再次进入了等待状态,输出如下:列表是空的...

线程 Google 将开始等待...

列表是空的...

线程 Runoob 将开始等待...

添加了新元素:'Hello!'

notifyAll 已调用,唤醒 synchedList 上等待的所有线程!

添加元素完成...

线程 Runoob 等待结束!

删除了元素 Hello!

线程 Google 等待结束!

列表是空的...

线程 Google 将开始等待...

中断的异常!

注意:

notify() 与 notifyAll() 方法只能被作为此对象监视器的所有者的线程来调用。如果当前线程不是此对象监视器的所有者的话会抛出 IllegalMonitorStateException 异常。

一次只能有一个线程拥有对象的监视器。一个线程要想成为对象监视器的所有者,可以使用以下 3 种方法:执行对象的同步实例方法使用 synchronized 内置锁对于 Class 类型的对象,执行同步静态方法toString() 方法public String toString()

描述:

用于返回对象的字符串表示形式。

参数:

无

返回值:

返回对象的字符串表示形式。默认返回格式:对象的 class 名称 + @ + hashCode 的十六进制字符串。

public class Test {public static void main(String[] args) {// toString() with Object Object obj1 = new Object();System.out.println(obj1.toString());Object obj2 = new Object();System.out.println(obj2.toString());Object obj3 = new Object();System.out.println(obj3.toString());}}// 以上程序执行结果为:// java.lang.Object@29453f44// java.lang.Object@5cad8086// java.lang.Object@6e0be858以上就是详解Java中Object 类的使用的详细内容,更多关于Java Object 类的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:Java源码解析之object类java中object类实例分析java中Object类4种方法详细介绍Java Object类和包装类深入解读一文搞懂Java顶层类之Object类的使用Java中的Object类用法总结

相关文章