Object中的方法
Clone方法
protected Object clone() throws CloneNotSupportedException
创建并返回此对象的一个副本。
修饰符为protected,保证了只有在该类 同一个包下 以及子类可以访问。但是如果子类和基类不在同一个包下,子类在进行访问的时候,只能访问自身从基类继承过来的protected方法,不能访问基类实例中受保护的clone方法。如果子类和基类在同一个包下,那么protected就相当于public。
原来对象修改某些属性后,clone之后的新对象的属性并不会发生变化。(如果属性值是一个引用,这就例外了,因为都指向同一块内存区域,这就是浅表复制。如果是深表复制,那么在拷贝的时候会把引用所指向的那个对象也拷贝过来,不是拷贝那个引用本身了,这样就可以做到原有对象和拷贝之后的新对象完全独立,一方的改变不会影响另外一方)。
Clone之后的对象和之前的对象的类型是一样的(getClass).
浅表拷贝:
在对某个对象拷进行clone时,对其是一无所知的,仅仅是简单的执行对属性的copy。
上述的拷贝过程,由于属性hireDay是一个引用(对象),那么在拷贝的时候只会把这个引用拷贝过来,新的对象和原来的对象都指向Date这块内存了。
那么如何实现深表拷贝呢?一种方法是通过对那些非基本数据类型的属性进行特殊的处理,重新定义clone方法。如下:
Class Employee implements Cloneable {
public object clone() throws CloneNotSupportedException {
Emploee clonedEmploee = (Employee)super.clone();
clonedEmploee.hireDay = (Date)hireDay.clone();
return clonedEmploee;
}
}
另外一种方法就是通过序列化,转换为流的方式进行读写。
在使用的时候要注意是使用浅表拷贝还是深表拷贝。
调用clone方法的对象所属的类必须实现Cloneable接口,重写clone方法,并设置访问修饰符为public,方法中调用super.clone()方法得到需要复制的对象。
equals方法
boolean equals(Object obj)
指示某个其他对象是否与此对象“相等”
==运算符判断两个引用是否指向同一个对象。
Object类中的equal方法:
public boolean equals(Object obj)
{
return (this == obj);
}
判断调用equals方法的引用和传进来的引用是否一致,也就是是否指向同一个对象。
特点
自反性(reflexive):任何非空引用x,x.equals(x)返回为true。
对称性(symmetric):任何非空引用x和y,x.equals(y)返回true当且仅当y.equals(x)返回true。
传递性(transitive):任何非空引用x和y,如果x.equals(y)返回true,并且y.equals(z)返回true,那么x.equals(z)返回true。
一致性(consistent):两个非空引用x和y,x.equals(y)的多次调用应该保持一致的结果,(前提条件是在多次比较之间没有修改x和y用于比较的相关信息)。
约定:对于任何非空引用x,x.equals(null)应该返回为false。
并且覆写equals()方法时,应该同时覆写hashCode()方法,反之亦然。(满足hashcode的常规协定,也就是对于两个相等的对象返回的hashcode值应该一样,对于两个不相等的对象,返回的hashcode值不一定要不同)
hashCode方法
int hashCode()
返回该对象的哈希码值。
当重写了equals方法,必须重写hashcode方法。
这个方法返回一个整型值(hash code value),如果两个对象被equals()方法判断为相等,那么它们就应该拥有同样的hash code。Object类的hashCode()方法为不同的对象返回不同的值,Object类的hashCode值表示的是对象的地址。
hashCode 的常规协定是:
1.在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
2.如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
3.如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
toString方法
String toString()
返回该对象的字符串表示。
当打印引用,如调用System.out.println()时,会自动调用对象的toString()方法,打印出引用所指的对象的toString()方法的返回值,因为每个类都直接或间接地继承自Object,因此每个类都有toString()方法。
Object类中的toString()方法定义如下:
public String toString()
{
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
finalize方法
protected void finalize( )
关键字protected是防止在该类之外定义的代码访问finalize()标识符。
垃圾回收器准备释放内存时,回收某个对象时,会先调用该对象的finalize方法。
1 对象不一定会被回收
2 垃圾回收不是析构函数
3 垃圾回收只与内存有关
4 垃圾回收和finalize都是靠不住的,只要JVM还没有到快耗尽内存的地步,它是不会浪费时间进行垃圾回收的。
有时当撤消一个对象时,需要完成一些操作。例如,如果一个对象正在处理的是非Java 资源,如文件句柄或window 字符字体,这时你要确认在一个对象被撤消以前要保证这些资源被释放。为处理这样的状况,Java 提供了被称为收尾(finalization )的机制。使用该机制你可以定义一些特殊的操作,这些操作在一个对象将要被垃圾回收程序释放时执行。
在 Java 中,当你创建一个对象时,Java 虚拟机(JVM)为该对象分配内存、调用构造函数并开始跟踪你使用的对象。当你停止使用一个对象(就是说,当没有对该对象有效的引用时),JVM 通过垃圾回收器将该对象标记为释放状态。
当垃圾回收器将要释放一个对象的内存时,它调用该对象的finalize() 方法(如果该对象定义了此方法)。垃圾回收器以独立的低优先级的方式运行,只有当其他线程挂起等待该内存释放的情况出现时,它才开始运行释放对象的内存。(事实上,你可以调用System.gc() 方法强制垃圾回收器来释放这些对象的内存。)
getClass方法
public final Class getClass()
返回一个对象运行时的类。
例子:Student类继承Person类
如果知道一个实例,那么你可以通过实例的“getClass()”方法获得该对象的类型类,如果你知道一个类型,那么你可以使用“.class”的方法获得该类型的类型类。
notify方法
唤醒在此对象监视器上等待的单个线程。
notifyAll方法
唤醒在此对象监视器上等待的所有线程。
wait方法
void wait() //导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
void wait(long timeout) //导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或notifyAll() 方法,或者超过指定的时间量。
void wait(long timeout, int nanos) //导致当前的线程等待,直到其他线程调用此对象的notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。