Object常用方法讲解(附带使用示例)

1. 参考

Java基础教程之Object类,Object类干货详解
wait、notify、notifyAll的理解与使用

2. 实战

clone()方法
对象 clone 方法默认是浅拷贝,深拷贝需要重写clone方法。

浅拷贝:拷贝出来的对象,如果部分属性是引用类型,那么这些属性引用的是旧对象的属性
深拷贝:新对象跟旧对象引用的完全不一样,各自各的

看这个图就懂了,这就是为什么改基本类型、String类型、引用类型的属性,会得到不一样的结果
Object常用方法讲解(附带使用示例)_第1张图片
重写clone方法,实现深拷贝

public class Person implements Cloneable{
    private String name;
    private int age;
    private int[] ints;

    public Person(String name, int age, int[] ints) {
        this.name = name;
        this.age = age;
        this.ints = ints;
    }

	public int[] getInts() { return ints;}
    public void setInts(int[] ints) { this.ints = ints;}
    public String getName() { return name;}
    public void setName(String name) { this.name = name;}
    public int getAge() { return age;}
    public void setAge(int age) { this.age = age;}

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     *  深拷贝
     * */
    @Override
    public Object clone() throws CloneNotSupportedException {
        Person person = new Person(name,age);
        int[] ints = new int[this.ints.length];
        System.arraycopy(this.ints,0,ints,0,ints.length);
        person.setInts(ints);
        return  person;
    }
}
public class CloneTest  {

    @Test
    public void test() throws CloneNotSupportedException {
        int[] ints = {1,2,3};
        Person person = new Person("zhangxiangyang",23,ints);
        Person clonePerson = (Person) person.clone();
    }
}

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

import java.util.*;
 
class RunoobTest extends GregorianCalendar {
    public static void main(String[] args) {
        try {
            // 创建 RunoobTest 对象
            RunoobTest cal = new RunoobTest();

            System.out.println("Finalizing...");
            cal.finalize();
            System.out.println("Finalized.");
 
        } catch (Throwable ex) {
            ex.printStackTrace();
        }
    }
}

equals()方法、hashCode()方法

必须声明一下,equals()重写与hashCode()重写没有必然关系。
- equals():原方法对比的是两个对象的地址,如果你想比较属性值来判断是否同一个对象,那就重写。
- hashCode():原方法对比的是两个对象的地址的hashCode值,如果你想比较属性值来判断是否同一个对象,那就重写。
package jianlejun.study;
 
public class Student {
	private String name;// 姓名
	private String sex;// 性别
	private String age;// 年龄
	private float weight;// 体重
	private String addr;// 地址
	
	// 重写hashcode方法
	@Override
	public int hashCode() {
		int result = name.hashCode();
		result = 17 * result + sex.hashCode();
		result = 17 * result + age.hashCode();
		return result;
	}
 
	// 重写equals方法
	@Override
	public boolean equals(Object obj) {
		if(!(obj instanceof Student)) {
       // instanceof 已经处理了obj = null的情况
			return false;
		}
		Student stuObj = (Student) obj;
		// 地址相等
		if (this == stuObj) {
			return true;
		}
		// 如果两个对象姓名、年龄、性别相等,我们认为两个对象相等
		if (stuObj.name.equals(this.name) && stuObj.sex.equals(this.sex) && stuObj.age.equals(this.age)) {
			return true;
		} else {
			return false;
		}
	}
 
	public String getName() { return name;}
	public void setName(String name) {this.name = name;}
	public String getSex() { return sex;}
	public void setSex(String sex) { this.sex = sex;}
	public String getAge() { return age;}
	public void setAge(String age) { this.age = age;}
	public float getWeight() { return weight;}
	public void setWeight(float weight) { this.weight = weight;}
	public String getAddr() { return addr;}
 	public void setAddr(String addr) { this.addr = addr;}
}

wait()、notify()、notifyAll()方法

  1. wait( ),notify( ),notifyAll()都不属于Thread类,而是属于Object基础类,也就是每个对象都有wait( ),notify( ),notifyAll( )的功能,因为每个对象都有锁,锁是每个对象的基础,当然操作锁的方法也是最基础了。
  2. 当想要调用wait( )进行线程等待时,必须要取得这个锁对象的控制权(对象监视器),一般是放到synchronized(obj)代码中。
  3. wait()操作会立即释放其持有的对象锁,当执行完同步代码块就会释放对象的锁。
public class EarlyNotify {
    private static String lockObject = "";
    // 添加一个状态标志,让 waitThread 调用 wait 方法前先判断状态是否已经改变了没。
    private static boolean isWait = true;

    public static void main(String[] args) {
        WaitThread waitThread = new WaitThread(lockObject);
        NotifyThread notifyThread = new NotifyThread(lockObject);
        notifyThread.start();
        
        Thread.sleep(3000);
        
        waitThread.start();
    }

    static class WaitThread extends Thread {
        private String lock;

        public WaitThread(String lock) { this.lock = lock;}

        @Override
        public void run() {
            synchronized (lock) {
                try {
                    while (isWait) {
                        System.out.println(Thread.currentThread().getName() + "  进去代码块");
                        System.out.println(Thread.currentThread().getName() + "  开始wait");
                        lock.wait();
                        System.out.println(Thread.currentThread().getName() + "   结束wait");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class NotifyThread extends Thread {
        private String lock;
        public NotifyThread(String lock) { this.lock = lock;}

        @Override
        public void run() {
            synchronized (lock) {
                System.out.println(Thread.currentThread().getName() + "  进去代码块");
                System.out.println(Thread.currentThread().getName() + "  开始notify");
                lock.notifyAll();
                isWait = false;
                System.out.println(Thread.currentThread().getName() + "   结束开始notify");
            }
        }
    }
}

Object常用方法讲解(附带使用示例)_第2张图片

你可能感兴趣的:(12万字Java面经总结,Java,java)