Object类中的一些方法

  1. object类有哪些方法?各是什么意思?
    一:wait()和notify()以及notifyAll():
    wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到得到锁或者被中断。wait(long timeout)设定一个超时的间隔,如果在规定的时间内没有获得锁就返回。
    调用该方法后当前线程就进入睡眠状态,直到以下事件发生:
    (1)其他线程调用了该对象的notify()方法
    (2)其他线程调用了该对象的notifyAll()方法
    (3) 其他线程调用了interrupt中断该线程
    (4)时间间隔到了
    此时该线程就可以被调度了,如果是被中断的话就抛出一个InterruptedException异常。

notify()方法:该方法唤醒在该对象上等待的某个线程
notifyAll()方法:该方法唤醒在该对象上等待的所有线程。

再说一个题外话:wait()方法和sleep()方法的区别:
1:这两个方法来自不同类分别是Thread和Object
2: 最主要是sleep方法没有释放锁,而wai't方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3: wai't,notify和notifyAl'l只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
4: sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
5: sleep是Thread类的静态方法,sleep的作用是让线程休眠制定时间,在时间达到时恢复,也就是说sleep将在接到时间达到事件恢复线程执行。wait时Object的方法,也就是可以对任意一个对象调用方法,调用wai't方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。

二: hashcode方法和equals方法
首先说以下两个方法之间的关系:

  1. 如果两个对象相同(用equals比较返回true),那么他们的hashcode值一定相等
    2.如果两个对象的hashCode相同,它们并不一定相同(即用equals比较返回false)。
    即:
    1、当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode() 必须为true;
    2、当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2) 必须为false。
    为什么要重写equals?
    如果不重写equals,那么比较的将是对象的引用是否指向同一块内存地址,重写之后目的是为了比较两个对象的value值是否相等。特别指出利用equals比较八大包装对象(如int,float等)和String类(因为该类已重写了equals和hashcode方法)对象时,默认比较的是值,在比较其它自定义对象时都是比较的引用地址。
    什么是hashcode?
    hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。由于为了提高程序的效率才实现了hashcode方法,先进行hashcode的比较,如果不同,那没就不必在进行equals的比较了,这样就大大减少了equals比较的次数。一个很好的例子就是在集合中的使用,我们都知道java中的List集合是有序的,因此是可以重复的,而set集合是无序的,因此是不能重复的,那么怎么能保证不能被放入重复的元素呢,单靠equals方法一样比较的话,如果原来集合中以后又10000个元素了,那么放入10001个元素,难道要将前面的所有元素都进行比较,看看是否有重复,这个效率可想而知,因此hashcode就应遇而生了,java就采用了hash表,利用哈希算法(也叫散列算法),就是将对象数据根据该对象的特征使用特定的算法将其定义到一个地址上,那么在后面定义进来的数据只要看对应的hashcode地址上是否有值,如果有那么就用equals比较,如果没有则直接插入,这样就大大减少了equals的使用次数,执行效率就大大提高了。继续上面的话题,为什么必须要重写hashcode方法,其实简单的说就是为了保证同一个对象,保证在equals相同的情况下hashcode值必定相同,如果重写了equals而未重写hashcode方法,可能就会出现两个没有关系的对象equals相同的(因为equals都是根据对象的特征进行重写的),但hashcode确实不相同的。

三: clone方法
clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象。那么在java语言中,有几种方式可以创建对象呢?

1 使用new操作符创建一个对象
2 使用clone方法复制一个对象

那么这两种方式有什么相同和不同呢? new操作符的本意是分配内存。程序执行到new操作符时, 首先去看new操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。而clone在第一步是和new相似的, 都是分配内存,调用clone方法时,分配的内存和源对象(即调用clone方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域, 填充完成之后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部。

Person p = new Person(23, "zhang");
        Person p1 = p;
        
        System.out.println(p);
        System.out.println(p1)

当Person p1 = p;执行之后, 是创建了一个新的对象吗? 首先看打印结果:
com.pansoft.zhangjg.testclone.Person@2f9ee1ac
com.pansoft.zhangjg.testclone.Person@2f9ee1ac
可已看出,打印的地址值是相同的,既然地址都是相同的,那么肯定是同一个对象。p和p1只是引用而已,他们都指向了一个相同的对象Person(23, "zhang") 。 可以把这种现象叫做引用的复制。


image.png

而下面的代码是真真正正的克隆了一个对象。

Person p = new Person(23, "zhang");
        Person p1 = (Person) p.clone();
        
        System.out.println(p);
        System.out.println(p1)

从打印结果可以看出,两个对象的地址是不同的,也就是说创建了新的对象, 而不是把原对象的地址赋给了一个新的引用变量:
com.pansoft.zhangjg.testclone.Person@2f9ee1ac
com.pansoft.zhangjg.testclone.Person@67f1fba0


image.png

四:getClass方法
final方法,获得运行时类型。

五:toString方法
该方法用得比较多,一般子类都有覆盖。

六:finalize方法
该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用。

你可能感兴趣的:(Object类中的一些方法)