Java 对象模型中:
- 所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例。
- 所有的类都最终继承自Object类,Class是类,那么Class也继承自Object。
那到底是先有Class还是先有Object? JVM 是怎么处理这个“鸡·蛋”问题呢?
Java 对象模型中:
那到底是先有Class还是先有Object? JVM 是怎么处理这个“鸡·蛋”问题呢?
小二那天去面试,碰到了这个问题:“instanceof 关键字是如何实现的?”面试官希望他能从底层来分析一下,结果小二没答上来,就来问我。
我唯唯诺诺,强装镇定,只好把 R 大的一篇回答甩给了他,并且叮嘱他:“认认真真看,玩完后要是还不明白,再来问我。。。”
作者:RednaxelaFX,整理:沉默王二,链接:https://www.zhihu.com/question/21574535/answer/18998914
在知乎上看到 R 大的这篇回答,着实感觉需要分享给在座的各位 javaer 们,真心透彻。
首先是先问是不是再问为什么系列。
在JDK8u的jdk项目下做个很粗略的搜索:
“二哥,最近在我阅读 Java 11 的字符串源码,发现和 Java 8 的有很大不同。”三妹的脸上洋溢着青春的微笑😊,甜美地说道:“String 类的源码已经由 char[]
优化为了 byte[]
来存储字符串内容,为什么要这样做呢?”
“开门见山地说,从 char[]
到 byte[]
,最主要的目的是节省字符串占用的内存空间。内存占用减少带来的另外一个好处,就是 GC 次数也会减少。”我用右手的大拇指凑了一下眼镜解释道。
重写(Overriding)算是 Java 中一个非常重要的概念,理解重写到底是什么对每个 Java 程序员来说都至关重要,这篇文章就来给大家说说重写过程中应当遵守的 12 条规则。
重写带来了一种非常重要的能力,可以让子类重新实现从超类那继承过来的方法。在下面这幅图中,Animal 是父类,Dog 是子类,Dog 重新实现了 move()
方法用来和父类进行区分,毕竟狗狗跑起来还是比较有特色的。
今天我们来谈谈 Java 中的 hashCode()
方法。众所周知,Java 是一门面向对象的编程语言,所有的类都会默认继承自 Object 类,而 Object 的中文意思就是“对象”。
Object 类中就包含了 hashCode()
方法:
public native int hashCode();
在前面学习优先级队列的时候,我们曾提到过 Comparable和Comparator,那这篇继续以面试官的角度去切入,一起来看。
那天,小二去马蜂窝面试,面试官老王一上来就甩给了他一道面试题:请问Comparable和Comparator有什么区别?小二差点笑出声,因为三年前,也就是 2021 年,他在《二哥的Java进阶之路》上看到过这题😆。
“二哥,你能给我说说为什么 String 是 immutable 类(不可变对象)吗?我想研究它,想知道为什么它就不可变了,这种强烈的愿望就像想研究浩瀚的星空一样。但无奈自身功力有限,始终觉得雾里看花终隔一层。”三妹的这句话里满是彩虹屁的味道。
“既然三妹你说话这么好听,那我们就开始吧!”我愉快的心情就好像吃了两罐蜂蜜一样(😂)。
一个类的对象在通过构造方法创建后如果状态不会再被改变,那么它就是一个不可变(immutable)类。它的所有成员变量的赋值仅在构造方法中完成,不会提供任何 setter 方法供外部类去修改。
为了让铁粉们能白票到阿里云的服务器,我当了整整两天的客服,真正体验到了什么叫做“为人民群众谋福利”的不易和辛酸。正在我眼睛红肿打算要休息之际,三妹跑过来问:“Java 的可变参数究竟是怎么一回事?”我一下子又清醒了,我爱 Java,我爱传道解惑,也享受三妹的赞许(😂)。
可变参数是 Java 1.5 的时候引入的功能,它允许方法使用任意多个、类型相同(is-a
)的值作为参数。就像下面这样。
public static void main(String[] args) {
print("沉");
print("沉", "默");
print("沉", "默", "王");
print("沉", "默", "王", "二");
}
public static void print(String... strs) {
for (String s : strs)
System.out.print(s);
System.out.println();
}
“三妹,今天我们来补一个小的知识点:Java 基本数据类型缓存池。”我喝了一口枸杞泡的茶后对三妹说,“考你一个问题哈:new Integer(18) 与 Integer.valueOf(18)
的区别是什么?”
“难道不一样吗?”三妹有点诧异。
“不一样的。”我笑着说。
new Integer(18)
每次都会新建一个对象;Integer.valueOf(18)
会使⽤用缓存池中的对象,多次调用只会取同⼀一个对象的引用。