阿里的面试题里面有个题很奇妙:你知道Object类里面有哪些方法吗?

绝大部分猿类都知道 有hashcode 、equals 、clone、toString

只有部分人会回答有 wait和notify,notifyall,finalize

我原来也不清楚wait和notify居然是在Object里面定义的~~~~囧

由此会衍生很多问题出来:比如在日常工作中会重写哪些方法?为什么重写equals一定要重写hashcode?深clone和浅clone说下你的认识?wait和notify为什么要定义在Object中,wait和notify是怎么使用的?wait和sleep的区别?finalize的效果和使用场景?

然后我们来一一看下这些问题。

1、一般会重写的的方法:

hashcode、equals、tostring

2、为什么重写equals方法一定要重写hashcode

首先我们看下equals的javadoc里面的说明:

* @return  {@code true} if this object is the same as the obj
* argument; {@code false} otherwise.
含义:只有当equals前后的两个对象是同一个对象的时候,才返回true,否则就是false。

也就是说,我们如果我们不重写hashcode,两个你认为相同的obj,可能出现不同的hashcode,而hashmap和set之类的数据结构都是依赖hashcode来进行的,

如果不重写hashcode就有可能碰到这个情况,当equals为true的时候,hashcode必须完全相同。当hashcode不同的时候,equals必须为false。

如果不覆盖equals,那么默认equals比较的引用的内存地址,如果覆盖了,你就需要自己去保证这些内容的一致。

还有一系列看上去很唬人实际上很好理解的原则在里面:

/*
  * 重写equals必须注意:
  *   1 自反性:对于任意的引用值x,x.equals(x)一定为true
  *   2  对称性:对于任意的引用值x 和 y,当x.equals(y)返回true,y.equals(x)也一定返回true
  *   3 传递性:对于任意的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也一定返   回 true
   * 4 一致性:对于任意的引用值x 和 y,如果用于equals比较的对象信息没有被修改,
   *           多次调用x.equals(y)要么一致地返回true,要么一致地返回false
   *   5 非空性:对于任意的非空引用值x,x.equals(null)一定返回false
   **/

3、深clone和浅clone

Object里面有个clone方法是浅clone,clone出来的类,新的对象和原来的对象并不是同一个引用,但是如果类中属性存在引用类型,那么新的类的对应属性也会指向这个引用。

也就是,你如果修改了新对象的引用对象的内容,原来的对象也会发生改变。

如果我们需要clone出来一个完全不同的类,可以通过实现cloneable的protected的clone方法,来确定,

可以通过自己拼接一份新的对象返回,不过对于嵌套层次比较深的类,这是个很浩大的工程。当然也有简单的做法,把对象序列化,然后再反序列化回来其实就是一个新的了。

这种clone之后完全不同的两个对象的情况,就是深clone了。

4、wait和notify为什么要定义在Object中,wait和notify是怎么使用的

wait和notify为什么不在Thread中而是在Object中,其实这个地方稍微有点绕。

我们就假设一种情况吧:A对象,100个线程,线程Thread[1] 持有A对象的锁,其它99个都想使用A,然后就在等待锁。A用完了,怎么通知其他99个?我们是Thread[1]持有其它99个线程的,然后分别去通信通知他们还是通过Object对象直接告诉其他99好呢?

这个很明显吧,我们并不能确定外围有多少个线程,我们只能确定,Object都可以作为锁,然后为什么不用对象本身来管理这些消息通知呢?我们只要在其中一个线程使用完成锁之后,对象把锁丢地上说:兄弟们我的钥匙扔地上了,你们看着办啊。。而不是之前拿钥匙的人,因为这个人没法认识其他所有人,但是凡是关心这个对象的,这个对象肯定都是知道的。

所以这个地方的wait和notify其实Object中定义的~比较口语化,我也不知道怎么更加优雅的表达,那我们就抄一段放这里吧:

5、sleep和wait的区别

sleep是Thread类的静态方法,它生效的也仅仅是当前线程,而不能用 某线程.sleep() .

wait是持有该对象锁的线程主动放弃锁,交出monitor。

sleep本身并不释放所和资源,而只是等待一段时间。wait是交出了锁和资源,后面如果再想获取,需要看自己的实现了。

6、finalize

Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。finalize方法在Object类中是protected方法,也就是你可以自己去重写这个方法,但是除非很特殊的情况,一般没必要自己去重写。

这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。

当垃圾回收器(garbage colector)决定回收某对象时,就会运行该对象的finalize()方法。值得C++程序员注意的是,finalize()方法并不能等同与析构函数。Java中是没有析构函数的。C++的析构函数是在对象消亡时运行的。由于C++没有垃圾回收,对象空间手动回收,所以一旦对象用不到时,程序员就应当把它delete()掉。所以析构函数中经常做一些文件保存之类的收尾工作。但是在Java中很不幸,如果内存总是充足的,那么垃圾回收可能永远不会进行,也就是说filalize()可能永远不被执行,显然指望它做收尾工作是靠不住的。

那么finalize()究竟是做什么的呢?它最主要的用途是回收特殊渠道申请的内存。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种JNI(Java Native Interface)调用non-Java程序(C或C++),finalize()的工作就是回收这部分的内存。

也就是说,finalize并不保证执行以后就会把内存释放掉,而是会到执行后的下一次垃圾回收才有机会被回收掉。

有料面试题之--Object里面的方法的更多相关文章

  1. 方法object面试题分析:7JAVA中Object的clone方法详解-克隆-深克隆

    时间紧张,先记一笔,后续优化与完善.     每日一道理 翻开早已发黄的页张,试着寻找过去所留下的点点滴滴的足迹.多年前的好友似乎现在看来已变得陌生,匆忙之间,让这维持了多年的友谊变淡,找不出什么亲切 ...

  2. .NET面试题解析(04)-类型、方法与继承

      系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 做技术是清苦的.一个人,一台机器,相对无言,代码纷飞,bug无情.须梦里挑灯,冥思苦想,肝血暗耗,板凳坐穿 ...

  3. 理解JAVA - 面向对象(object) - 属性,方法

    理解JAVA - 面向对象(object) - 属性,方法 多态的体现:    向上造型,父类接收子类对象:向上造型:    从父类角度看不到子类独有的方法:面向对象,人类认知世界的方式:生活中每天都 ...

  4. 利用Object.prototype.toString方法,实现比typeof更准确的type校验

    Object.prototype.toString方法返回对象的类型字符串,因此可以用来判断一个值的类型. 调用方法: Object.prototype.toString.call(value) 不同 ...

  5. Object类clone方法的自我理解

    网上搜帖: clone()是java.lang.Object类的protected方法,实现clone方法: 1)类自身需要实现Cloneable接口 2)需重写clone()方法,最好设置修饰符mo ...

  6. Cloneable接口和Object的clone()方法

    为什么要克隆 为什么要使用克隆,这其实反映的是一个很现实的问题,假如我们有一个对象: public class SimpleObject implements Cloneable { private ...

  7. JavaScript:Object.prototype.toString方法的原理

    在JavaScript中,想要判断某个对象值属于哪种内置类型,最靠谱的做法就是通过Object.prototype.toString方法. var arr = []; console.log(Obje ...

  8. Object类的方法

    一 Object:类Object是类层次结构的跟类,每个类都使用Object作为超类,每个类都是直接或者间接的继承自Object类. Object类的方法: ①public int hashCode( ...

  9. javascript Object的新方法

    今天复习es6,又看到Object的一堆方法,与es5的表现又有不一致,耗费了一整天,整理一下: 前几天在司徒正美的书里又看到了es5 Object的字眼,为了向下兼容,大神们也是牛逼的整理出一系列i ...

  10. Object 及toString() 方法的重写

    Object: 是所有的类的父类  ,Object中所有的方法 , 子类都能使用  ,   接口不是Object子类. Person: /*将父类的equals方法 重写 * 不改变父类的源代码 eq ...

随机推荐

  1. JS数组sort比较函数

    转载:http://www.cnblogs.com/ljchow/archive/2010/06/30/1768683.html 我们知道,数组的sort方法可以对数组元素进行排序,默认是按ASCII ...

  2. Error: EACCES: permission denied, access '/usr/local/lib/node_modules'

    sudo chown -R username /usr/local/lib/node_modules 注:username要具有/usr/local/lib/node_modules的读写权限

  3. [日常] Apache Order Deny,Allow的用法

    Order Deny,Allow的用法:影响最终判断结果的只有两点:1. order语句中allow.deny的先后顺序,最后的是最优先的:2. allow.deny语句中各自包含的范围. 常用:Or ...

  4. 简单说说SpringMVC

    距离上一次开发SpringMVC项目已经过去了大半年,有些细节已经开始遗忘,今天复习一下 先从标签说起: 和struts有各种配置文件不同,spring用标签开发. 1.@Controller在Spr ...

  5. hdu 1430

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  6. java Date 当天时间戳处理

    1. 代码 private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; private static Date ...

  7. Vue2.0项目打包后只能访问首页,其他页面路径错误找不到

    原因是你使用了vue-router的history,可以尝试去掉  // mode:"history",

  8. intent调用代码总结

    进入联系人界面 Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(People.CO ...

  9. Btree并发内存回收

    在并发写Btree原理剖析 一文中提到,节点内存回收有可能导致内存突增以及影响写性能.本文将阐述最近对内存回收的改进,多线程可并行回收内存. 回收策略 采用基于版本的机制,Btree全局维护一个版本号 ...

  10. 《SQL Server 2008从入门到精通》--20180704

    XML查询技术 XML文档以一个纯文本的形式存在,主要用于数据存储.不但方便用户读取和使用,而且使修改和维护变得更容易. XML数据类型 XML是SQL Server中内置的数据类型,可用于SQL语句 ...