Java class、Object、Class 的区别

Java的对象模型中:

    1. 所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例。
    2. 所有的类都最终继承自Object类,Class是类,那么Class也继承自Object。
这个问题中,第1个假设是错的:java.lang.Object是一个Java类,但并不是java.lang.Class的一个实例。后者只是一个用于描述Java类与接口的、用于支持反射操作的类型。这点上Java跟其它一些更纯粹的面向对象语言(例如Python和Ruby)不同。
而第2个假设是对的:java.lang.Class是java.lang.Object的派生类,前者继承自后者。

 

 

Java class、Object、Class 的区别?

按我的理解,

Class只是一个名字比较特殊的类,是关键字class修饰的类,一般应用于反射,只是名称比较特殊而已,可以通过Class类型来获取其他类型的元数据(metadata),比如字段,属性,构造器,方法等等,可以获取并调用。

class是一个关键字,是用来修饰类

Object是一个特殊的类,所有的类都继承该类,包括Class也继承Object。

类是一个语法概念,是一个抽象的概念,所有class修饰的都属于这个概念。所有类都有一个(属性,好像也不是属性)class返回含有该类元数据的Class类的实例。(有点不好描述,就是比如Class a=Test.class)。

 

 

 

1.所有的类都是Class类的实例,Object是类,那么Object也是Class类的一个实例。

这句话是完全混乱以及不知所云的。当然,我知道你错在哪儿,我试着给你理一下。

中文说到“类”,对应的英文是class,ok,这是一个前提,不要认为他们是不同的东西。一个class,描述的是一个抽象的数据结构,或者说,一个class,是一个抽象数据结构的定义,记住,这里说到的class,是一个语法上的概念,并没有实体跟它对应。

接下来,在JDK中,提供了两个预定义的class, Object以及Class。按照Java规范,所有的class(注意我这里对class和Class的大小写形式的区分使用,class代表的是语法概念,Class代表JDK中提供的Class数据结构)都是Object的子类,所以, Class一定是Object的子类,它用来描述所有的class的meta信息,比如它有多少个字段啊,有些什么方法啊,等等这些数据结构信息。

接下来,看实例是什么?实例是指根据抽象的class定义在运行时声明的一段内存区间,该内存区间可以按照class的定义进行合法的访问。所以,Object不是实例,Object是一个class,可以用一个Class的实例来描述。

最后这句话有点绕,回头看看你的原文,“所有的类都是Class类的实例”, 类就是类,就是class,是一个语法概念,是你自己定义的一个抽象数据结构,跟实例无关,所以,自然的,Object只是一个class,而不是Class的实例。

看下面的代码

Class cls = Object.class;

Class cls = new Class(new byte[2048]);

Object obj = cls.newInstance();

Object obj = new Object();

* 注意,第二行代码实际上是不成立的,但从逻辑上比较容易理解,所以我就生造了这样一个调用。

第一行代码中,Class是一个class, Object也是一个class,同时,Object.class指向一个Class实例,该实例可以描述Object的数据结构(实际上,就是内存布局)。

第二行代码,可以用来解释,那个Object.class又是哪儿来的,实际上,就是从硬盘上读入的class文件的二进制数据,然后通过new一个Class的实例,并传入加载的class文件的二进制数据,Class的内部实现会解释二进制数据并生成相应的内部描述数据。

第三行代码,Class的newInstance方法总是通过Class的实例才能调用的,因为如上所述,我们通过实例化一个Class的手段来得到一个类的meta描述。

第四行代码,是我们通常创建实例的手段,从逻辑上,你可以认为,第4行代码实际上就等同于第二行代码加上第三行。

最后,在实际的JVM实现中,并不这样简单,但你需要首先从逻辑上理解这些概念之间的关系,然后,自己再去深入学习。再强调一遍,我这里的描述,都只是逻辑上等价的描述,并不是实际情况。
 
 

先有Class还是先有Object?

真是一个好问题!
我大概讲一下我的想法,对不对不知道,只是想和大家交流一下。
应该是先有Object类再有Class类。
在实现Class类的时候,先继承了Object类,然后编译成.class的字节码,这样就能被JVM加载了。
虚拟机加载了所有类。这些类在虚拟机里都能被Class类进行描述,Object类也是,它的字段,方法什么的也都能被Class类进行描述和表示。而这个表示类的Class实例是由虚拟机装载类时自动构造的。
so,题主明白了吧,这里面不是谁先谁后的关系,而是他们压根不在同一个世界里。Object在Class类之前,那是在编译期;Class能表示Object类,那是在JVM中。这个跟鸡和蛋之间的关系是两码事,要分开在不同的场景里讨论。

刚看到这个问题的时候我愣了一下,好像从没思考过这个问题,不得不说题主的眼光很独到。
 
 
class字节码加载到jvm,然后在堆内存生成一个class对象。然后对象指向字节码,你就可以通过class对象快乐的操作了。
 
 
 
 
posted @ 2018-11-13 15:37  panchanggui  阅读(7202)  评论(0编辑  收藏  举报