周末比较无聊,在浏览论坛的时候,偶然看到一个程序猿提问的问题,他时这样提问的:突然想到一个很菜的问题, 倒底先有Object还是先有Class?所有类都是Object的子类, Object是作为一个类(class)而存在, 而每一个类又都对应一个class对象(object), 那么Object和Class到底是一个什么样的逻辑关系呢? 想来想去, 感觉有点陷入了"是鸡生蛋还是蛋生鸡"的怪圈了。
现在我们就来一起分析和研究一下,这样有意思的问题,我感觉还是应该多多分享的,因为像这样的问题,弄明白了,你会感觉到有很大的成就感的。在我们分析之前,你认为是先有Class还是先有Object呢?
我在知乎上看到了同样的问题,他是这么说的:
在Java的对象模型中:
所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例。
所有的类都最终继承自Object类,Class是类,那么Class也继承自Object。
其实在他描述的这个问题中,很明显第一个点是不对的,因为在JDK中,提供了两个预定义的class, Object以及Class。按照Java规范,所有的class(注意这里对class和Class的大小写形式的区分使用,class代表的是语法概念,Class代表JDK中提供的Class数据结构)都是Object的子类,所以, Class一定是Object的子类,它用来描述所有的class的meta信息,比如它有多少个字段啊,有些什么方法啊,等等这些数据结构信息。所以这里第二点是正确的。
第一点中,说所有的类都是Class类的实例,不对,类就是类,就是class,是一个语法概念,是我们人为自己定义的一个抽象数据结构,跟实例无关,所以,Object只是一个class,而不是Class的实例。
小编不才,只能分析道这里。但是对于这个问题,知乎上的一个大神叫RednaxelaFX,从事JVM研发的回答的比较好,我移植过来,供大家参考一下。
RednaxelaFX是这样说的:
这个问题中,第1个假设是错的:java.lang.Object是一个Java类,但并不是java.lang.Class的一个实例。后者只是一个用于描述Java类与接口的、用于支持反射操作的类型。这点上Java跟其它一些更纯粹的面向对象语言(例如Python和Ruby)不同。
而第2个假设是对的:java.lang.Class是java.lang.Object的派生类,前者继承自后者。
虽然第1个假设不对,但“鸡蛋问题”仍然存在:在一个已经启动完毕、可以使用的Java对象系统里,必须要有一个java.lang.Class实例对应java.lang.Object这个类;而java.lang.Class是java.lang.Object的派生类,按“一般思维”前者应该要在后者完成初始化之后才可以初始化…
事实是:这些相互依赖的核心类型完全可以在“混沌”中一口气都初始化好,然后对象系统的状态才叫做完成了“bootstrap”,后面就可以按照Java对象系统的一般规则去运行。JVM、JavaScript、Python、Ruby等的运行时都有这样的bootstrap过程。
在“混沌”(boostrap过程)里:
JVM可以为对象系统中最重要的一些核心类型先分配好内存空间,让它们进入[已分配空间]但[尚未完全初始化]状态。此时这些对象虽然已经分配了空间,但因为状态还不完整所以尚不可使用。
然后,通过这些分配好的空间把这些核心类型之间的引用关系串好。到此为止所有动作都由JVM完成,尚未执行任何Java字节码。
然后这些核心类型就进入了[完全初始化]状态,对象系统就可以开始自我运行下去,也就是可以开始执行Java字节码来进一步完成Java系统的初始化了。
看到这里不知道你明白了没有,不过没有明白也没有关系,大家可以在下面进行评论,说一下自己的观点,仅供娱乐和放松,像这种问题弄不明白也很正常。有意思的事才值得大家一起讨论嘛!
共同学习,写下你的评论
评论加载中...
作者其他优质文章