论坛首页 入门技术论坛

关于Java实例化的本质

浏览 12512 次
该帖已经被评为新手帖
作者 正文
   发表时间:2010-04-22  
Java实例化的本质:每次使用new操作符,实际上都在实例化一个类的对象,这就是Object类。换言之,无论什么类的实例化,在最开始都是先实例化一个Object类。然后以此类为基础进一步的增加新的属性(级联构造器),相当于给Object类的对象穿上一件件的衣服。

大家说说看,能不能这样理解java实例化的本质。
   发表时间:2010-04-23  
楼主说的太过于笼统了吧...我更关心"以此类为基础进一步的增加新的属性",关于父类子类的构造方法,静态变量初始化...等等...
0 请登录后投票
   发表时间:2010-04-23  
Java 中所有对象都是Object 的子类。。要实例化子类,必须先实例化了父类。。这个是肯定的,lz这样说好像没什么意思。。。
本质应该看JVM的实现。
0 请登录后投票
   发表时间:2010-04-23  
我是通过级联构造器来理解的,比如实例化一个String类的对象,实际上是实例化了一个Object类的实例,运行object类的构造器,然后在object类对象的基础上构造string类的对象。可以理解成看看string比object多了哪些属性和方法,把多的东西都加上,然后运行String类的构造器,完成stirng类的构造。
大家说这样的理解对吗?
0 请登录后投票
   发表时间:2010-04-23  
string和object属于底层的吧。
应该不会遵循级联构造器
0 请登录后投票
   发表时间:2010-04-23  
深入Java虚拟机可以 读读
0 请登录后投票
   发表时间:2010-04-23  
继承就是这样
0 请登录后投票
   发表时间:2010-04-23  
文章上了首页,如果没点实质性的东西,那么楼主杯具的可能性在80%以上。。。
0 请登录后投票
   发表时间:2010-04-23  
thelongestday 写道
我是通过级联构造器来理解的,比如实例化一个String类的对象,实际上是实例化了一个Object类的实例,运行object类的构造器,然后在object类对象的基础上构造string类的对象。可以理解成看看string比object多了哪些属性和方法,把多的东西都加上,然后运行String类的构造器,完成stirng类的构造。
大家说这样的理解对吗?





public MyObject(xxx)
{
    super()://去找Object了
    //...其它操作
}
0 请登录后投票
   发表时间:2010-04-23   最后修改:2010-04-23
当new一个对象的时候发生了什么?我就给大家讲讲吧,如果不对的地方,还请大家指正
如new MyObject();

1:寻找类定义
jvm会在自己的一个名叫“方法区”的内存块中,寻找名叫“MyObject”的Class对象(注意class也是一个对象,该对象记录了所有类的定义),如果有,则按照Class对象的定义,生成一个MyObject对象。

2:加载类定义
如果“方法区”中没有名为“MyObject”的Class对象,jvm会用当前类的类加载器(classloader)从当前的classpath路径寻找名为"MyObject.class"的文件,如果找到,则将文件进行分析,转换为Class对象存放在“方法区”中,否则抛出“ClassNotFoundException”。对于jdk的class,jvm启动时,会用启动类加载器加载,对于用户的class,则会用应用程序类加载器实时加载,所谓实时加载,指的是遇到的时候再加载,而不是预先一次性加载。关于类加载器,有三级,jvm严格的限制了每一级的加载权限,加载模式为“双亲委托模式”,加载任何类,都先由父加载器加载。


3:给对象分配内存空间
找到MyObject的类定义后,jvm在内存“堆”中,开辟一个空间,该空间按照MyObject类定义开辟,并将该空间中的各个内存段设置默认值,对应的就是对象的属性初始化默认值。


4:对象的初始化顺序
对象的初始化都先从父类开始,顺序如下:
给父类静态变量默认值
对父类静态变量赋值
执行父类静态块

给当前类静态变量默认值
对当前类静态变量赋值
执行当前类静态块

给父类变量默认值
对父类变量赋值
执行父类构造函数

给当前类变量默认值
对当前类变量赋值
执行当前类构造函数

5:对象构造完成



还有一点要提醒楼主,当你new一个String的时候,只是生成一个String对象,而没有生成Object对象,Object的类定义在“方法区”这块内存中,当new String的时候,jvm会检查String的父类,找出父类的定义,并找出哪些是String可以拥有的,然后按照筛选出来的父类定义和String本身的类定义,在堆中分配一个内存块(就是俗称的生成了一个对象),而没有专门为String的父类Object分配空间。

其实你可以想想下,如果像你那么说,new一个String的时候,还会生成一个Object对象,那java简直没法使用了,因为Obejct是所有对象的父类,使用任何对象都会生成一个Object对象,还不算其他的父类。如果这样,多大的内存也不够用,即使内存够了,CPU也会忙死,因为这么多对象,后台的gc执行一次收集清除,都累得够呛了。特别是现在的gc机制都是按代收集的,对象巨多,年轻代很容易满,导致gc收集启动,应用程序会停顿。这样的系统谁能用呢?
3 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics