1、类的成员变量、构造函数、成员方法的初始化过程

当一个类使用new关键字来创建新的对象的时候,比如Person per = new Person();JVM根据Person()寻找匹配的类,然后找到这个类相匹配的构造方法,这里是无参构造,如果程序中没有给出任何构造方法,则JVM默认会给出一个无参构造。当创建一个对象的时候一定对调用该类的构造方法,构造方法就是为了对对象的数据进行初始化。JVM会对给这个对象分配内存空间,也就是对类的成员变量进行分配内存空间,如果类中在定义成员变量就赋值的话,就按初始值进行运算,如果只是声明没有赋初始值的话,JVM会按照规则自动进行初始化赋值。而成员方法是在对象调用这个方法的时候才会从方法区中加载到栈内存中,用完就立即释放内存空间。

初始化过程:成员变量->构造函数->成员方法。

package com.yyq;
/**
* Created by Administrator on 2015-10-30.
*/
class Person {
int age;
String name;
public Person() {
System.out.println("This is Person()");
System.out.println("Name:" + this.name + "; Age:" + this.age);
}
public void show() {
System.out.println("This is show()");
System.out.println("Name:" + this.name + "; Age:" + this.age);
}
}
public class Exercise01 {
public static void main(String[] args) {
Person per = new Person();
per.show();
per.age = 30;
per.name = "Wendy";
per.show();
}
}
输出结果:
This is Person()
Name:null;  Age:0
This is show()
Name:null;Age:0
This is show()
Name:Wendy;Age:30

2、类的成员变量、静态代码块、构造代码块、局部代码块、构造方法、成员方法的初始化过程

静态代码块是在类中方法外成员位置出现,用了static修饰;一般用于给类进行初始化。静态代码块在这个类第一次被调用或实例化的时候就会被执行。 静态代码块只会执行一次,一般会用来初始化一些值,并且在所有对象中全局共享。构造代码块在类中方法外成员位置出现;可以把多个构造方法中共同的代码放到一起,每次调用构造都执行,并且在构造方法前执行,对对象进行初始化。局部代码块在方法中出现,局部位置;限定变量的生命周期,及早释放,提高内存利用率。

初始化过程:静态代码块(只执行一次)->构造代码块(每次调用构造方法都执行)->构造方法。执行顺序与代码块所在的具体位置无关。

局部代码块的初始化顺序由具体位置决定。

package com.yyq;
/**
* Created by on 2015-10-30.
*/
class CodeBlockDemo {
//静态代码块
static {
int a = 1000;
System.out.println("静态代码块1:"+a);
}
//构造代码块
{
int x = 100;
System.out.println("构造代码块1:"+x);
}
//构造方法
public CodeBlockDemo(){
System.out.println("Exercise02()");
}
//构造方法
public CodeBlockDemo(int a){
System.out.println("Exercise02(int a):"+a);
}
//构造代码块
{
int y = 200;
System.out.println("构造代码块2:"+y);
}
//静态代码块
static {
int b = 2000;
System.out.println("静态代码块2:"+b);
}
}
public class Exercise02{
public static void main(String[] args) {
//局部代码块
{
int x = 10;
System.out.println("局部代码块1:"+x);
}
//出错:找不到符号
//System.out.println(x);
System.out.println("演示一---------------");
CodeBlockDemo ex1= new CodeBlockDemo();
System.out.println("演示二---------------");
CodeBlockDemo ex2 = new CodeBlockDemo();
System.out.println("演示三---------------");
CodeBlockDemo ex3 = new CodeBlockDemo(1);
{
int y = 20;
System.out.println("局部代码块2:"+y);
}
}
}
输出结果:
局部代码块1:10
演示一---------------
静态代码块1:1000     ==>静态代码块只是在该类第一次创建对象的时候才会被调用,而且初始化顺序与代码所在具体位置无关
静态代码块2:2000
构造代码块1:100       ==>构造代码块在每次初始化对象的时候都会被调用,而且初始化顺序与代码所在具体位置无关
构造代码块2:200
Exercise02()
演示二---------------
构造代码块1:100       ==>构造代码块在每次初始化对象的时候都会被调用,而且初始化顺序与代码所在具体位置无关
构造代码块2:200
Exercise02()
演示三---------------
构造代码块1:100        ==>构造代码块在每次初始化对象的时候都会被调用,而且初始化顺序与代码所在具体位置无关
构造代码块2:200
Exercise02(int a):1
局部代码块2:20          ==>局部代码块只是简单的顺序执行程序,与实际位置有关

这里没有将成员变量和成员方法加入分析,但是我们可以知道,静态代码块在类加载的时候就已经初始化了,而成员变量是要在创建对象的时候才会根据构造方法进行分配内存,初始化赋值,所以如果你在静态代码块中打印成员变量或者成员变量赋值的话就会显示出错,显示要将变量类型改为static,而在构造代码块和构造方法中都能正常使用。

初始化过程:静态代码块(只执行一次)->成员变量(每次创建对象都会初始化赋值)->构造代码块(每次调用构造方法都执行)->构造方法(每次创建对象都会调用相匹配的构造方法)->成员方法(对象调用的时候运行)。

3、有继承关系的父类和子类的成员变量、构造方法、成员方法的初始化过程

在创建子类对象的时候会去调用子类的构造方法,其实子类的构造方法的第一条执行语句是super();即会自动去调用父类的无参构造方法,也就是说会自动去检测子类所继承的父类,并对父类的成员变量进行初始化操作。初始化完父类的成员变量、构造方法后,就初始化子类的成员变量和构造方法。因为子类会继承父类的非私有成员变量和成员方法(这里我把成员变量和成员方法都定义为默认访问权限),所以子类中如果定义了相同的成员变量,在初始化的时候就会被覆盖,而成员方法在调用的时候如果父类有子类没有,就执行父类的方法,如果父类没有子类有就执行子类的方法,如果父类有子类也有的话,那子类的成员方法就是复写了父类的成员方法,那最终执行就是子类的成员方法。

初始化过程:父类的成员变量->父类构造方法->子类成员变量->子类构造方法->父类/子类成员方法。

package com.yyq;
/**
* Created by Administrator on 2015-10-30.
*/
class Father{
int age = 40;
String name = "Father";
int num = 321;
public Father(){
System.out.println("Father()");
System.out.println("Name:"+name+"; Age:"+age+"; Num:"+num);
}
public void show(){
System.out.println("I am Father.");
}
public void play(){
System.out.println("Father play.");
}
};
class Son extends Father{
int age = 15;
String name = "Son";
public Son(){
System.out.println("Son()");
System.out.println("Name:"+name+"; Age:"+age+"; Num:"+num);
}
public void show(){
System.out.println("I am Son.");
}
public void study(){
System.out.println("Son play.");
}
}
public class Exercise03 {
public static void main(String[] args){
Son son = new Son();
son.show();
son.play();
son.study();
}
}
输出结果:

Father()

Name:Father; Age:40; Num:321

Son()

Name:Son; Age:15; Num:321

I am Son.

Father play.

Son play.

4、有继承关系的父类和子类的成员变量、静态代码块、构造代码块、构造方法,成员方法的初始化过程

因为如果有继承关系的子类和父类,在创建子类对象的时候会自动的去调用父类的构造方法,对父类的数据进行初始化。但是如果父类和子类都有静态代码块的话,那会先执行父类的静态代码块,接着执行子类的静态代码块,因为静态代码块不需要创建对象才能执行,所以在加载类的时候首先运行静态代码块,然后接着运行父类的构造代码块和父类的构造方法,最后才是运行子类的构造代码块和子类的构造方法。

初始化过程:父类静态代码块->子类静态代码块->父类构造代码块->父类构造方法->子类构造代码块->子类构造方法

package com.yyq;
/**
* Created by Administrator on 2015-10-30.
*/
class BaseClass{
static
{
System.out.println("静态代码块BaseClass");
}
{
System.out.println("构造代码块BaseClass");
}
public BaseClass() {
System.out.println("构造方法BaseClass");
}
}
class SonClass extends BaseClass {
static {
System.out.println("静态代码块SonClass");
}
{
System.out.println("构造代码块SonClass");
}
public SonClass() {
System.out.println("构造方法SonClass");
}
}
public class Exercise04 {
public static void main(String[] args){
SonClass son1 = new SonClass();
System.out.println("-------------------");
SonClass son2 = new SonClass();
}
}
输出结果:
静态代码块BaseClass
静态代码块SonClass
构造代码块BaseClass
构造方法BaseClass
构造代码块SonClass
构造方法SonClass
-------------------
构造代码块BaseClass
构造方法BaseClass
构造代码块SonClass
构造方法SonClass
 

Java对象相关元素的初始化过程的更多相关文章

  1. Java类变量和成员变量初始化过程

    一.类的初始化 对于类的初始化:类的初始化一般只初始化一次,类的初始化主要是初始化静态成员变量. 类的编译决定了类的初始化过程. 编译器生成的class文件主要对定义在源文件中的类进行了如下的更改: ...

  2. java中类的创建及初始化过程

    java中类的创建及初始化过程无外乎两种情况,其一为单类的创建及初始化,其二具有继承关系的父子类创建及初始化过程.     首先说简单的,单类的创建及初始化过程.在java中我们都知道绝大部分对象的创 ...

  3. Java类的实例化的初始化过程

    A a = new A(); new 创建对象过程: 1.类加载     代码验证 2.给对象在内存(堆)中分配空间(给属性赋值): 3.属性赋默认值: byte,short.int,long -&g ...

  4. java对象的几种创建过程

    java对象的创建过程 (1)用new 语句创建对象,这是最常用的创建对象方法. 下面用一个简单的存在继承关系的实例的创建,来叙述对象创建过程中的细节 概括如下: 执行顺序:(优先级从高到低.)静态代 ...

  5. 【深入理解Java虚拟机】类的初始化过程

    类的初始化过程 类的加载过程.png 加载 将 Class 文件以二进制的形式加载到内存中 验证 校验 Class 文件是否安全,是否被正确的修改等 准备 为类变量申请内存,设置默认值,(初始化变量的 ...

  6. 深入理解Java对象的序列化与反序列化的应用

    当两个进程在进行远程通信时,彼此可以发送各种类型的数据.无论是何种类型的数据,都会以二进制序列的形式在网络上传送.发送方需要把这个Java对象转换为字节序列,才能在网络上传送:接收方则需要把字节序列再 ...

  7. (二)Java对象与内存控制

    一.java的类变量和实例变量: java中的变量可分成两种:成员变量和局部变量. 1.局部变量包括以下几类: 方法内的局部变量:作用域为方法体. 代码块内的局部变量:作用域为代码块 形参:方法内的形 ...

  8. Java对象导论

    Java对象导论 1.1 抽象过程 万物皆对象. 程序是对象的集合(即:类),他们通过发送消息(调用方法)来告知彼此要做的. 每个对象都有自己的由其他对象所构成的存储(引用其他对象或基本类型,即组合) ...

  9. Java对象的序列化和反序列化介绍

    一.什么序列化和反序列化以及作用: java序列化是指把java对象转换为字节序列的过程,而java反序列化是指把字节序列恢复为java对象的过程 1.序列化: 1)对象序列化的最主要的用处就是在传递 ...

随机推荐

  1. TCL_事务控制语言

    TCL     transaction  事务   --  DML            定义为把一连串的操作作为单个逻辑工作单元处理                -----     例如:银行转账 ...

  2. 【oracle】Enterprise Manager 无法连接到数据库实例。下面列出了组件的状态---个人解决方案

    最近在学习Oracle,平常喜欢使用EM查看数据库状态,但是在最近突然发现EM连接不上Oracle数据库了,不知道问题出在哪里,只好卸载了重装.但是,在使用了几天以后,又出现了相同的问题,于是下决心将 ...

  3. Spark Streaming揭秘 Day7 再探Job Scheduler

    Spark Streaming揭秘 Day7 再探Job Scheduler 今天,我们对Job Scheduler再进一步深入一下,对一些更加细节的源码进行分析. Job Scheduler启动 在 ...

  4. 概念:RPG与RPGLE的区别

    RPG是OPM编程模式,即RPG编程的代码不能编译成*MODULE:编译只能直接生成一个程序,*PGM.    RPGLE是ILE编程模式.OS/400环境下,ILE是集成开发环境.在ILE环境下,所 ...

  5. Oracle SQL的硬解析、软解析、软软解析

    Oracle中每条sql在执行前都要解析,解析分为硬解析.软解析.软软解析. Oracle会缓存DML语句,相同的DML语句会进行软解析.但不会缓存DDL语句,所以DDL每次都做硬解析.硬解析是一个很 ...

  6. 子查询优化成join关联查询时要注意一对多关系

    mysql> select * from t where t.id in (select t1.tid from t1); +------+ | id | +------+ | +------+ ...

  7. 备份了一个nginx的虚拟主机配置文件报错

    [root@localhost vhost]# service nginx restart 停止 nginx:[确定] 正在启动 nginx:nginx: [warn] conflicting ser ...

  8. easy ui 表单元素input控件后面加说明(红色)

    <%-- 上传图片到图库基本信息且将图片关联到图集 开始--%> <div id="win_AddPicLib" class="easyui-windo ...

  9. 基于SuperSocket实现的WebSocket(后端)

    关于WebSocket其实很早就想发了,奈何之前项目中的WebSocket的后端不是我做的,而我又想前后端都发出来和大家讨论讨论~于是挤出点时间研究了一下WebSocket的后端实现(所以才有了这篇文 ...

  10. mybatis随意sql语句

    mybatis的mapper.xml随意sql语句, 不管表之间存不存在关系, 都可以使用, 但注意resultMap中一定要指定查询数据返回的列 或 对象(其实就是多列封装到一个对象中) <? ...