Object
Object类为所有类的超类(父类,基类)
java创建对象的四种方法
- new 通过new来创建一个新的对象,这是最常见的创建对象的方法
- 反射 运用反射,调用java.lang.Class或者java.lang.reflect.Constructor类的newInstance()实例方法
- clone 调用对象的clone()方法
- 反序列化 调用java.io.ObjectInputStream 对象的 reanObject()方法,反序列化对象
new和反射都会明确的、显式的调用构造方法, clone是在内存上对已有对象的影印,所以不会调用构造方法, 反序列化是从文件中还原对象,也不会调用构造方法
方法
getClass() 获取该 Object 的运行时类
获取Class对象的3种方式
Class.forName()
Class clazz=Class.forName(“java.lang.String”);
类名.class
Class clazz=String.class;
对象.getClass()
Class clazz=new Cat().getClass();
equals() 判断对象是否相等
Object类的equals方法其实就等价于”==”,比较引用,建议覆盖
equals()的特点
自反性:对于任何非空引用值x,x.equals(x) 都应返回true。
对称性:对于任何非空引用值x 和y,当且仅当y.equals(x) 返回true 时,x.equals(y) 才应返回true
传递性:对于任何非空引用值x、y 和z,如果x.equals(y) 返回true,并且y.equals(z) 返回true,那么x.equals(z) 应返回true
一致性:对于任何非空引用值x 和y,多次调用x.equals(y) 始终返回true 或始终返回false
hashCode() 返回对象的哈希码值
默认的hashCode() 值是当前堆对象地址转换的一个整数,这个整数不是内存地址
当equals方法被重写时,通常有必要重写hashCode方法,以维护hashCode方法的常规协定:相对等的两个对象必须有相同的hashCode
- 当object1.euqal(object2)时为true, object1.hashCode() == object2.hashCode() 为true
- 当object1.hashCode() == object2.hashCode() 为false时,object1.euqal(object2)必定为false
- 当object1.hashCode() == object2.hashCode() 为true时,但object1.euqal(object2)不一定定为true
如果重写了equals()而没有重写hashCode()
例如在存储散列集合时(如Set),如果对象1.equals(对象2),但没有重写hashCode()的话,即两个对象拥有不同的hashCode,则在集合中将会存储两个值相同的对象,从而导致混淆
toString() 返回对象的字符串表示形式
getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
int i =10;
System.out.println(i); //是隐式的调用 System.out.println(i.toString());
但对象为引用类型时,i=null,
System.out.println(i);不会报错
System.out.println(i.toString());会抛出空指针异常
clone() 创建并返回此对象的副本
子类只有实现Cloneable接口,否则抛出CloneNotSupported异常。
Object的clone是浅拷贝
浅拷贝:将对象的所有变量拷贝到另一个对象,但两对象的成员引用变量没有拷贝,都指向同一个引用。也就是说浅拷贝只是拷贝当前对象,并没有拷贝对象内部的对象成员。
深拷贝:将对象以及对象内部的所有成员都拷贝到另一个对象中去。
反序列换就是一个深拷贝
public class Person implements Cloneable{
public class Pet {
String name = "hdog";
}
String name;
int age;
Pet pet = new Pet();
public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person();
Person p2 ;
p2 = (Person) p1.clone();
System.out.println(p1.equals(p2));
System.out.println(p1.hashCode()==p2.hashCode());
System.out.println(p1.pet.equals(p2.pet));
System.out.println(p1.pet.hashCode()==p2.pet.hashCode());
}
}
结果为 false,false,true,true
finalize() 垃圾回收
使用finalize方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
JVM保证调用finalize函数之前,这个对象是不可达的,但JVM不保证这个函数一定会被调用,另外,规范还保证finalize函数最多运行一次。
finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。
wait() 使当前线程等待
wait() 和 sleep() 的区别
wait 是Object类的方法。
调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态
sleep 是Thread类的方法。
sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复(线程回到就绪状态)
简单的说就是,wait会释放程序的锁,而sleep不会释放锁。
notify(),notifyAll() 唤醒线程
notify(): 唤醒正在等待此对象监视器上的单个线程
notifyAll() : 唤醒正在等待此对象监视器上的所有线程