java类的初始化和构造函数
本人小白一枚,看java类的初始化的时候好晕的说,我觉着书上尽管说的对。但总认为有些信息没说出来,没说清楚,看了好多文章博客的,如今有些感悟,来小写下总结,也算是为以后再次复习种个好果子。
先摘一下书上写的:
载入:将类的class文件读入内存,并为之创建一个java.lang.class对象。
连接:把类的二进制数据合并到JRE中,检查被载入的类是否有正确的内部结构,并和其它类协调一致。为类的静态FIELD分配内存,设置默认值,将类的二进制数据中的符号引用替换成直接引用。
初始化:主要对静态Field进行初始化。初始化方式两种:声明静态Field时指定的值。使用静态初始化块为其指定初始值。JVM会按他们的顺序运行。初始化包含下面步骤:
如果该类没有被载入和连接。则先载入并连接该类。
如果他的父类没有被初始化。则先初始化他的父类
如果类中有初始化语句,则系统依次运行。
看完之后我脑子里一直就盘旋着几个问题:
1、类的载入和初始化神马的和构造函数有啥关系和差别?
2、类的初始化会为实例属性分配内存吗?
3、假设我要创建一个实例对象。究竟是怎么个创建流程?
OK,假设你也有以上的疑问,那么我们一起来看看究竟是怎么回事!我会直接回答最后一个问题,当你把这个问题弄明确了,前面的就迎刃而解了。
public class Person{
static{staticInt = 6; }
{vInt =15; }
static int staticInt = 3;
int vInt = 10;
Person(){
staticInt = 9;
vInt = 20;
}
}
Person p = new Person();
JVM会看:
1)哎,有个变量p。然后就给它分配一个空间(这里的空间指的是指针,而不是实际的对象)
2)分完了以后发现它须要Person这个类来进行实例化,然后就到内存里找。看这个类有没有被载入到内存里来,假设有救直接用了。假设没有就会进行载入。我们就来说没有的情况
3)载入的时候。将类的class文件读入内存。并为之创建一个java.lang.class对象。
这里须要重点说一下。在创建这个对象的时候,就会保存这个类的全部信息。比方这个类有哪些属性(静态的非静态的都包含)。有哪些方法(静态的非静态的都包含),有什么代码块。都会被记录。
4)把类的二进制数据合并到JRE中。检查被载入的类是否有正确的内部结构,并和其它类协调一致。JVM跑到java.lang.class对象里看看,都有啥静态变量。为他们分配内存。设置默认值,将类的二进制数据中的符号引用替换成直接引用。
5)然后对静态Field进行初始化,初始化方式两种:声明静态Field时指定的值。使用静态初始化块为其指定初始值。JVM会按他们的顺序运行。这个地方须要注意:如上代码,静态的变量staticInt最后会被赋值为3,由于静态代码块在声明之前。JVM是先跑到java.lang.class对象看有什么静态变量,给他分个空间,然后再运行的声明和静态代码块语句。因此初始化之后值为3.
好了,345都是类的载入和初始化。我们再来看看都做了些什么:生成java.lang.class对象。有该类里的属性方法代码块的全部信息。再为静态属性分配了内存并运行了静态代码块。按
顺序把静态属性给初始化了。
这里并没有为非静态属性分配内存,也没有运行构造函数和非静态代码块,一句话
总结就是:记录下这个类的全部属性和方法代码块等信息。为静态的变量分内存并赋值。
初始化之后,如今JVM改依据这个初始化好的类信息来进行实例化了。先前被初始化好的静态变量会被全部实例共享。静态代码块将不会再被运行,相当于失效了。我们来看看JVM接下来要干嘛?
6)JVM跑到java.lang.class对象里看一看。有哪些实例变量须要分配内存的,跟静态变量类似的,JVM先给实例变量分内存,分完之后,运行代码块和声明,在这里vInt为10。
7)最后运行构造函数,运行完后。vInt变成了20,staticInt变成了9,然后改构造函数隐性的返回一个Person实例对象给变量p。
好了。讲完了,我们再看看12问题
1、类的载入和初始化神马的和构造函数有啥关系和差别?
仅仅要在类须要实例化的时候才会运行构造函数。而类的载入和初始化却在这些情况都会被运行:创建实例 调用静态方法 訪问某个静态Field(假设该变量还是final的,则在编译阶段就能确定下来,就不会初始化)
初始化某个类子类
2、类的初始化会为实例属性分配内存吗?
不会为实例属性分配,仅仅有在实例化的时候才会分内存
总结
1)将类的class文件读入内存,并为之创建一个java.lang.class对象。
2)把类的二进制数据合并到JRE中。检查被载入的类是否有正确的内部结构。并和其它类协调一致,并为静态变量分内存
3)为静态变量初始化赋值
以上为初始化顺序
4)为非静态变量分内存。并赋值
5)构造函数,返回构造好的对象
假设有子类父类关系的时候:
父类和子类的class文件都载入到内存,当父类。和子类有Static时。先初始化Static,再初始化子类的Static,
再初始化父类的其它成员变量->父类构造方法->子类其它成员变量->子类的构造方法。
有不正确的地方还望高手指出啊
java类的初始化和构造函数的更多相关文章
- 图示Java类的初始化顺序
Java类的初始化顺序 在开发中,知道Java类的初始化顺序才能让我们更加清楚地掌握程序的执行流程.先把结论贴出来,Java里,从图里的1~6,分别按顺序执行. 以下为代码验证阶段,一共三个类 ...
- java类的初始化和对象的创建顺序
学习java编程思想--类的初始化p146 类的加载顺序* 1加载器启动找到 xxx.class文件,通过extends关键字寻找基类,先加载基类* 2类初始化先初始化static成员变量和stati ...
- java类的初始化
转载:http://blog.csdn.net/moreevan/article/details/6968718 我们知道一个类(class)要被使用必须经过装载,连接,初始化这样的过程.下面先对这三 ...
- Java类的初始化与实例对象的初始化
Java对象初始化详解 2013/04/10 · 开发 · 1 评论· java 分享到:43 与<YII框架>不得不说的故事—扩展篇 sass进阶篇 Spring事务管理 Android ...
- java类的初始化顺序
在java中,当我们new一个对象时,对象中的成员,初始化块以及构造方法的加载是有一定的顺序的,看下面一副图: 一.单类(无基类)下的初始化顺序: public class Parent { stat ...
- [Java] 类的初始化步骤
前言 类的初始化过程,可在多线程环境下进行的,为了简化,本文介绍的单线程情况下的类初始化步骤. 此外,继承情况下的顺序不是本文焦点,本文重点在于一个类的内部字段的初始化顺序.想了解继承情况下的初始化情 ...
- 分析java类的初始化契机
分析java类的静态成员变量初始化先于非静态成员变量 依上图中当class字节码文件被jvm虚拟机加载到内存中依次经过 连接 验证:对字节码进行验证 准备:给静态变量分配内存并赋予变量类型各自的默 ...
- Java类的初始化过程及清理
一.类的数据成员初始化 Java中类的数据成员初试化可能有两种形式. 在定义类成员变量的地方直接提供初始化值(这是C++中不允许的) 在构造器中初试化.(Java中不存在类似C++中的初始化列表) 两 ...
- Java类的初始化顺序 (静态变量、静态初始化块、变量、初始...
很有意思的一篇文章 1.没有继承 静态变量->静态初始化块->变量->变量初始化块->构造方法 2.有继承的情况 父类静态变量->父类静态初始化块->子类静态变量- ...
随机推荐
- [转] Spring@Autowired注解与自动装配
1 配置文件的方法 我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. Boss ...
- NHibernate 继承映射(第十六篇)
在NHibernate的映射中,关于继承的映射策略有3种方式 单表继承 类表继承 具体表继承 另外还有一种比较特别的多态映射 隐式多态 下面分别来阐述NHibernate继承映射的各种策略要点. 一. ...
- JavaScript 开发的45个技巧
JavaScript是一个绝冠全球的编程语言,可用于Web开发.移动应用开发(PhoneGap.Appcelerator).服务器端开发(Node.js和Wakanda)等等.JavaScript还是 ...
- http-server 超轻量级web服务器
有的时候做前端,想要运行一些代码,但是又没有必要使用tomcat或者Apache http server,这个时候一个轻量级的简单的http server就可以搞定了. Http-server是基于n ...
- 十三.spring-boot使用spring-boot-thymeleaf
thymeleaf 比如freemaker的要高,thymeleaf是一个支持html原型的自然引擎,它在html 标签增加额外的属性来达到模板+数据的展示方式,由于 浏览器解释html时,忽略未定义 ...
- hibernate反向工程 (eclipse和myeclipse)【转】
myeclipse下hibernate反向工程: 1.选择myeclipse hibernate视图 2.建立与后台数据库的连接 1).configure database driver: 2).添加 ...
- pymongo常见的高级用法
pymongo是python中基于mongodb数据库开发出来的,比mongoengine要高级一些,也要好用一些. 基本的增删查改就不说了 insert() delete() find() upda ...
- 关于RECOVERY清除数据的分析
[前言] 讨论:双清和清空所有数据的问题 说明:以前写的帖子都写三清,那个是为了保险起见才叫大家三项清除,毕竟人都有刚开始的时候,但看了郭贤普的帖子<系统与数据兼容性测试>之后,我觉得有必 ...
- HDU5312 Sequence
题意:t组数据,每组数据给个m.问m最少能由几项形如3*n*(n-1)+1的数表示 eg 7=1(n=1)+1(n=1)+1(n=1)+1(n=1)+1(n=1)+1(n=1)+1(n=1); ...
- <input type = "submit"> 提交方式和用js的form.submit()有什么区别?
假设: A表单内有<input type="submit">,通过点击这个input来提交表单 B表单内没有<input type="submit&qu ...