java类加载时初始化的疑问
java类在实例化之前要先加载类,加载类的时候会对类进行初始化,而如果类初始化的时候需要用到类的实例,这样不就成死循环了么,当然这种情况下java的实现中是不会出现死循环的,这是为什么呢?
例如:
class T{ public static T t1 = new T(); public int i = 0; public static void main(String[] args){ T t2 = new T(); } }执行main方法的时候要先加载类T,初始化类T中的t1,这个时候类T只是加载完了,但还没有初始化完,还不能实例化对象的,这个时候new T(),java不应该判断类T没有初始化完,然后去初始化类T么?这样子就相当于递归调用自己一样,成死循环了,然而事实并不是这样的,那java是如何处理这种情况的呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
Shazi199 说的应该基本正确的。
涨知识了,这么久的问题了,还在专研,精神可嘉啊.
哥们现在有答案了吗 同困惑啊
回复
他说的仍然解决不了我们的疑问啊,我们的问题是: 类T在加载过程中,有一个static成员是 initialization时进行赋值 值为T的一个实例,但是这时T的实例不能创建成功啊,因为T还没加载完成啊,所以加载应该陷入停顿。
t1是属于类T的,所以我才有疑问啊,一个类要能new对象的前提是这个类已经被加载连接初始化过了,而在初始化类T的时候却需要生成T的对象,这不应该有问题么?
你这里的t1是个static的变量,它不会在T实例化的时候进行初始化,而是在T被加载的时候初始化,因为它是属于类T的,而不是类T的对象的。所以当你去掉static的时候,就会造成在实例化的时候继续实例化形成死循环。
为什么加上static 就不会死循环呢?
回复
你要去了解static是什么意思
回复
我知道static的值是在加载类的时候初始化的,但是new T()的前提是 T这个类已经被加载连接初始化过了,而在初始化T类的时候执行的new T(),这个时候T这个class 还没有初始化完啊。
你把static去掉就死循环了
类的加载过程不是由类加载->类链接->类初始化 才算类加载完毕么,难道在类链接之后,类初始化之前就可以使用这个类来new对象了?
回复
由此我又产生了一个疑问,如果类不是在这三都必须完成之后就可以New对象,那它是在类加载之后就可以new还是在链接之后就可以new?
看来是你理解的不对,实际上类的代码早就已经被加载完毕可以使用了,这时就开始对类的static块和static成员进行处理,因此作为static成员t1就可以开始实例化了。
实例化的时候首先会初始化所有非static成员,然后执行构造函数,由于你这里的构造函数没有提供,默认就会执行无参的空构造函数。假如你在这里提供一个构造函数:public T(){T.t1=new T();},显然不需要去掉static就会死循环。
你的问题在于错误地认为必须全部“运行”了一遍才算是加载完成。