Object

来源:互联网 发布:天价域名排 编辑:程序博客网 时间:2024/06/05 08:48

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种方式

  1. Class.forName()

    Class clazz=Class.forName(“java.lang.String”);

  2. 类名.class

    Class clazz=String.class;

  3. 对象.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() : 唤醒正在等待此对象监视器上的所有线程