Java面试必问:Object类核心方法底层原理与高频考点
(拍大腿)哎我说!每次Java面试都逃不过Object类的灵魂拷问对吧?明明感觉会了,被面试官连环追问就支支吾吾?别慌!今天咱们把Object类扒得底裤都不剩,看完保你下次面试能跟面试官Battle三百回合!
一、为什么面试官总爱问Object类?
(抓头发)很多萌新想不通:这破类不就几个方法吗?有啥好问的?偷偷告诉你个行业秘密:??考察Object类就是检验Java基本功的试金石??!上个月我当技术面试官,10个候选人里8个说不清wait()和notify()为什么在Object里。你说该不该挂他们?
举个真实场景:
java复制public class MyClass { // 这里自动继承Object的11个方法 }
你造吗?就连空类都带着这11个"祖传方法",就像人生下来自带呼吸功能一样重要。现在知道为啥面试必考了吧?
二、getClass():类信息的时光胶囊
▍底层原理大揭秘
这个方法的实现其实是个本地方法:
java复制public final native Class<?> getClass();
在HotSpot虚拟机里,每个对象头都存着指向类元数据的指针。说人话就是——对象身份证上的户籍地址!
▍高频考点三连杀:
- ??getClass()和instanceof有什么区别???
- getClass()严格判断类型是否相同
- instanceof考虑继承关系
- ??Class对象是单例吗???
- 相同类加载器加载的同名类是同一个Class实例
- ??反射会触发类加载吗???
- 调用getClass()不会,Class.forName()会!
(突然想到)等等,类加载器不同会导致getClass()返回不同结果吗?必须的啊!这可是实现热部署的关键原理!
三、hashCode():对象的内存身份证
▍默认实现有多魔幻?
在32位JVM中,默认返回的是对象头指针的后31位;64位JVM则会做异或运算压缩到31位。但别记这些数字!重点记住:
- ??默认hashCode不等于内存地址??(虽然有关联)
- ??对象移动(GC)后hashCode不变??(写屏障保证的)
▍夺命连环问:
- 两个对象hashCode相同,equals一定为true吗?
- 错!哈希碰撞了解一下?
- System.identityHashCode()和hashCode()有什么区别?
- 前者强制使用默认算法,后者可能被重写
- 为什么HashMap用(n-1)&hash计算索引?
- 比取模运算快10倍以上!
四、equals():对象界的"大家来找茬"
▍方法契约三原则:
- 自反性:x.equals(x)必须true
- 对称性:x.equals(y) == y.equals(x)
- 传递性:x.equals(y)且y.equals(z),则x.equals(z)
(敲黑板)去年我们团队就因为违反对称性出过线上事故:新来的用instanceof判断,导致子类对象和父类对象比较结果不对称!
▍死亡陷阱题:
java复制new BigDecimal("1.0").equals(new BigDecimal("1")) // 返回啥?
答案让人大跌眼镜——false!因为scale(小数位数)不同。所以BigDecimal比较要用compareTo()!
五、wait/notify:多线程界的牛郎织女
▍灵魂拷问:为什么在Object里?
因为Java的锁是对象级别的啊!每个对象都有个等待队列,就像医院候诊室:
- wait():交出锁去候诊区排队
- notify():护士叫下一个病人
▍血泪教训:
某金融系统曾因错误使用导致线程饿死:
java复制synchronized(lock) { while(!condition) { lock.wait(); // 正确姿势 // lock.wait(1000); 更好的选择 } }
要是用if代替while,遇到虚假唤醒就完犊子了!
六、clone():对象的复制术
▍深拷贝VS浅拷贝:
- 浅拷贝:就像复印通讯录,号码还是同一个
- 深拷贝:连对方手机都克隆一部新的
▍面试毒瘤题:
java复制// 不实现Cloneable接口会怎样? @Override protected Object clone() throws CloneNotSupportedException { ... }
答案:运行时抛异常!这个设计被无数人吐槽——为啥不用编译时检查?Java设计者说这是历史遗留问题...
七、finalize():垃圾回收前的遗言
▍为什么被Java9标记为废弃?
- 执行时机不确定(可能永远不执行)
- 性能差(拖慢垃圾回收)
- 可能导致死锁(在finalize里搞事情)
替代方案直接用Cleaner类:
java复制Cleaner.create(obj, () -> System.out.println("对象被回收啦!"));
说点得罪人的大实话
做了十年Java面试官,发现很多工作五年的老手,照样在Object类问题上翻车。比如上周面试个架构师,问他"为什么wait()需要放在同步块里",支支吾吾说"可能是规范要求"(笑cry)。
不过说真的,现在Java17都出了,很多新特性比如Record类、密封类,都在帮我们简化这些基础操作。但万变不离其宗,Object类的设计思想永远值得琢磨。下次面试再被问到,记得反问面试官:"您觉得Java设计者把wait()放在Object类合理吗?" 说不定能反客为主哦!
(突然拍脑袋)等等!你确定自己真的理解hashCode的生成规则了?赶紧打开IDE写个demo验证下,别被我的文章带沟里去了!
本文由嘻道妙招独家原创,未经允许,严禁转载