【求解】关于类的Class对象的一些疑惑?

23glh 2013-09-08 09:35:01
《JAVA编程思想》中说每当编写并且编译了一个新类时,就会产生一个Class对象(被保存在一个同名的.class文件中),程序运行的时候JVM也是先检查类对应的class对象是否被加载,如果未加载,JVM会根据类名查找.class文件,并将其载入。一旦某个类的Class对象载入内存,他就被用来创建这个类的所有对象。有一些网上视频和资料说Class对象就是类编译后的字节码文件(.class文件,不知道Class cls=类名.class ;这种取得Class对象的方式后面的“类名.class”是不是类的字节码文件)。综上所述:也就是说每个类Class对象是在类编译后就产生了的,并且在加载类的时候会把Class对象加载到内存。然而我们学校课本以及图书馆查的书上说:Class对象是在加载类时由JVM或者调用类加载器中的defineClass方法自动构造的。也就是说Class对象是在类加载的时候由java虚拟机创建的。这样我就矛盾了,我有以下一些想请教高手们:
(1)这个Class对象到底是编译类后就产生的(甚至就是所说的字节码文件)还是加载类时产生的?
(2)class LoadedClass{//细节暂时省略}
class Test{
public static void main(String[] args){
Class cls=LoadedClass.class;
}
}
这里面是通过“类名.class”的方式获取类Class对象的。而“类名.class”是和类编译后的字节码文件的全称是一样的,难道这就是视频中说的类的字节码文件就是一个类的Class的对象吗?如果是的话,一个字节码文件能赋值给一个引用类型的变量吗?(不过有的说“class”是一个字面常量,可以通过类调用来获取类的Class对象)。
(3)class LoadedClass{
static{
System.out.println(“类LoadedClass载入”);
}
public LoadedClass(){
System.out.println(“类LoadedClass实例化”);
}
}

class Test{
public static void main(String[] args){
System.out.println(“以下是通过.class的方式取得LoadedClass类的Class对象”);
Class cls=LoadedClass.class;
}
}
运行结果:
以下是通过.class的方式取得LoadedClass类的Class对象

通过“类名.class”方式可以取得Class的对象,由运行结果看出此时静态代码块没有执行,也就是说类并没有加载,那么我们课本上说:Class对象是在加载类时由JVM或者调用类加载器中的defineClass方法自动构造的。此时类并没有加载,按这种说法就说JVM就还没有创建Class对象,但是现在“类名.class”方式取得的Class对象是哪里来的呢。
(4)在Test类中添加:System.out.println(cls);语句,结果打印的是:class LoadedClass;
这个变量cls是引用类型变量,按理说如果是打印其他的对象,一般不是用@连接的类名和对象地址,这里怎么不是呢,是不是重写了Class类的toString()了导致的?

我说的可能有点混乱,但是现在查资料要么是说Class对象在类编译后就产生了,加载类就是要加载Class对象,也就是字节码文件(表明类加载之前就已经有了类的Class对象了,)。要么是说Class对象是在加载类时由JVM或者调用类加载器中的defineClass方法自动构造的(表明Class对象是加载类的时候产生的)。
那么:java.lang.Class类的class对象到底是在编译后生成的(存在.class文件中,或者就是.class文件),还是在JVM加载类时生成的?或者说这两个Class对象之间有什么样的关系?是同一个class对象吗?请高手们能给我解释一下,在此谢谢各位!
...全文
219 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
23glh 2013-09-09
  • 打赏
  • 举报
回复
引用 3 楼 a1006570862 的回复:
Java源程序(.java文件)在经过 Java编译器 编译之后就被转换成 Java字节代码(.class 文件) JVM会执行该类的静态代码段,动态加载和创建Class 对象 楼主这和c++的静态绑定动态绑定是一样的
很感谢你的解答,有些书上就是你的这个意思,加载类的时候动态创建Class对象,但是有些书上不是,有些书上说的是每当编写并编译了一个java类后就产生了一个Class对象,保存在同名的.class文件中(包括网上好多都这么说),甚至有些视频就是直接说类对应的Class对象就是类字节码文件(每个字节码文件就是一个Class对象)。 如果是按你说的那个意思: class LoadedClass{ static{ System.out.println(“类LoadedClass载入”); } public LoadedClass(){ System.out.println(“类LoadedClass实例化”); } } class Test{ public static void main(String[] args){ System.out.println(“以下是通过.class的方式取得LoadedClass类的Class对象”); Class cls=LoadedClass.class; } } 运行结果: 以下是通过.class的方式取得LoadedClass类的Class对象 通过“类名.class”方式可以取得Class的对象,由运行结果看出此时静态代码块没有执行,也就是说类并没有加载,那么我们课本上说:Class对象是在加载类时由JVM或者调用类加载器中的defineClass方法自动构造的。此时类并没有加载,按这种说法就说JVM就还没有创建Class对象,但是现在“类名.class”方式取得的Class对象是哪里来的呢?
地下室森林 2013-09-09
  • 打赏
  • 举报
回复
Java源程序(.java文件)在经过 Java编译器 编译之后就被转换成 Java字节代码(.class 文件) JVM会执行该类的静态代码段,动态加载和创建Class 对象 楼主这和c++的静态绑定动态绑定是一样的
23glh 2013-09-09
  • 打赏
  • 举报
回复
引用 1 楼 a1006570862 的回复:
1.编译时生成的class类是一个文件,用来存储jvm能执行的指令集和类的信息. 2.JVM要运行程序就要在jvm中找到执行的指令,没有class对象就没有相应的指令.所有要加载class,把class加载到了JVM就会在JVM的方法区里生成类信息也就是class对象,等你在代码里有new操作时,就会在JVM的堆区里生成一个实例每个new都会有不同的实例. 所以class类的class对象只是一个概念,
那请问是不是说类的Class对象是在加载类的时候JVM创建的呢
地下室森林 2013-09-09
  • 打赏
  • 举报
回复
1.编译时生成的class类是一个文件,用来存储jvm能执行的指令集和类的信息. 2.JVM要运行程序就要在jvm中找到执行的指令,没有class对象就没有相应的指令.所有要加载class,把class加载到了JVM就会在JVM的方法区里生成类信息也就是class对象,等你在代码里有new操作时,就会在JVM的堆区里生成一个实例每个new都会有不同的实例. 所以class类的class对象只是一个概念,

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧