摘要

Java基本的对象初始化过程,子类的初始化,以及涉及到父类和子类的转化时可能引起混乱的情况。

1. 基本初始化过程:

对于一个简单类的初始化过程是:

static 修饰的模块(static变量和static 块)  ---> 按照代码顺序依次执行。

|

实例变量  及非static模块---> 按照代码顺序依次执行。

|

构造函数 ---> 执行对应的构造函数。

子类的初始化过程。

父类static修饰的模块

|

子类static修饰模块

|

父类实例变量和非static块

|

父类对应构造函数。当子类对应构造函数中没有显示调用时调用的是父类默认的构造函数。

|

子类实例变量和非static块

|

子类构造函数

Class的static模块是唯一的,所以只初始化一次。所有类的实例公用Class的static模块。

static模块的初始化条件: ( From: 引用1 )

(1)遇到new、getstatic、putstatic 或 invokestatic这4条字节码指令时,如果类还没初始化,则触发初始化。对应场景是:new实例化对象时、读或设置一个静态字段时(被final修饰,已在编译器把结果放入常量池的静态字段除外),以及调用一个类的静态方法时

(2)对类进行反射调用时

(3)初始化子类。但父类还没有初始化时,先触发父类初始化

(4)当虚拟机启动时,需指定一个需要执行的主类(包含main方法),虚拟机会先初始化该类

2. 关于覆盖和隐藏

覆盖:被覆盖的方法相当于被擦除了,不可恢复(即使类型强制转换也无法调用)。

隐藏:一直保存的某个位置,等需要的时候可以继续使用(类型强制转换后可以调用)。

关于父类子类之间的覆盖和隐藏关系: (From :引用2)

1. 父类的实例变量和类变量能被子类的同名变量隐藏。

2. 父类的静态方法被子类的同名静态方法隐藏,父类的实例方法被子类的同名实例方法覆盖。

3. 不能用子类的静态方法隐藏父类的实例方法,也不能用子类的实例方法覆盖父类的静态方法,否则编译器会异常。

4. 用final关键字修饰的最终方法不能被覆盖。

5. 变量只能被隐藏不会被覆盖,子类的实例变量可以隐藏父类的类变量,子类的类变量也可以隐藏父类的实例变量。

涉及的典型情况:

前提:

-----------------------------------------

class B extends A{……}

-----------------------------------------

(1) B instanceB = new B();

instanceB的初始化过程如第一部分中:子类的初始化过程。

此时instanceB中实际上有一个super的全部信息(除了父类中被覆盖的实例方法),但是当前的引用是子类的信息(如果子类中没有的变量和方法则是从父类继承来)。

(2)A instanceA = new B();

此时父类A的变量和静态方法会将子类的变量和静态方法隐藏。instanceA此时唯一可能调用的子类B的地方就是子类B中覆盖了父类A中的实例方法。

执行 B instanceB = (B) instanceA; 后

此时instanceB相当于 B instanceB = new B();

注意:

(1) 这里唯一的覆盖的情况:父类的实例方法被子类的同名实例方法覆盖。

这里方法调用变量时,实际上是带有一个默认的this的。也就是此实例方法中调用的是当前Class的值。涉及到继承的情况时,要十分注意super,this的情况。

(2) 在初始化的时候,有两个阶段。第一步是申请空间,第二步是赋值。

具体见:

static的值和final static值在初始化时的区别。(引用1)

子类覆盖父类实例方法时,调用子类的实例方法,而此时子类的实例方法调用了子类中的变量(此时static变量已经初始化,但是实例变量并没有初始化)。(引用2)

这段代码来自引用2,如何精炼,如此有趣。值得一看。

class Parent{
         int x=10;
         public Parent(){
              add(2);
         }
         void add(int y){
              x+=y;
         }
    }
     class Child extends Parent{
         int x=9;
         void add(int y){
              x+=y;
         }
         public static void main(String[] args){
              Parent p=new Child();
              System.out.println(p.x);
         } 
    }

引用 1. 类加载机制:

http://blog.csdn.net/kai_wei_zhang/article/details/8234146

引用 2. 隐藏和覆盖,以及一个好例子:

http://www.cnblogs.com/binjoo/articles/1585342.html

引用 3. 隐藏和覆盖

http://renyanwei.iteye.com/blog/258304

引用 4. 基本的初始化过程

http://www.cnblogs.com/miniwiki/archive/2011/03/25/1995615.html

Java父类子类的对象初始化过程的更多相关文章

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

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

  2. java基础---类加载和对象创建过程

    类中可以存在的成员: class A{ 静态成员变量: 非静态成员变量: 静态函数: 非静态函数: 构造函数 A(..){...} 静态代码块 static{...} 构造代码块 {...} } 类加 ...

  3. java基础课程笔记 static 主函数 静态工具类 classpath java文档注释 静态代码块 对象初始化过程 设计模式 继承 子父类中的函数 继承中的构造函数 对象转型 多态 封装 抽象类 final 接口 包 jar包

    Static那些事儿 Static关键字 被static修饰的变量成为静态变量(类变量) 作用:是一个修饰符,用于修饰成员(成员变量,成员方法) 1.被static修饰后的成员变量只有一份 2.当成员 ...

  4. Java 子类实例化对象的过程

    子类实例化是否会实例化父类? 不会.父类在子类实例化过程中是并没有被实例化,java中new子类没有实例化父类,只是调用父类的构造方法初始化了,子类从父类继承来的属性,这个调用是子类的对象调用的父类的 ...

  5. Java的对象初始化过程

    成员变量(字段)初始化顺序 在一个类里初始化的顺序是由成员变量在类里面的定义的顺序来决定的.即使成员变量大量散布于类的各个方法定义的中间,那些成员变量仍会在调用任何方法之前得以初始化,甚至在构造函数调 ...

  6. Java中对象初始化过程

    Java为对象初始化提供了多种选项. 当new一个对象的时候,对象初始化开始: 1.首先,JVM加载类(只加载一次,所以,即使多次new对象,下面的代码也只会在第一次new的时候执行一次),此时, 静 ...

  7. 综合: Java 对象初始化过程

    class Fu { Fu() { show(); } void show() { System.out.println("xixi"); } } class Zi extends ...

  8. [Think In Java]基础拾遗1 - 对象初始化、垃圾回收器、继承、组合、代理、接口、抽象类

    目录 第一章 对象导论第二章 一切都是对象第三章 操作符第四章 控制执行流程第五章 初始化与清理第六章 访问权限控制第七章 复用类第九章 接口 第一章 对象导论 1. 对象的数据位于何处? 有两种方式 ...

  9. Java内存区域与对象创建过程

    一.java内存区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则 ...

随机推荐

  1. Debug your C# project more efficiently

    I am a very beginner working with C# and Visual Studio 2013. When I debug my project, I always reope ...

  2. 【POJ2104】【整体二分+树状数组】区间第k大

    Description You are working for Macrohard company in data structures department. After failing your ...

  3. Android 学习手札(备注)

    1.在Android 应用程序中不能使用System.out.println(..)来输出信息,而要使用Log类中的静态方法输出调试信息. Log.d("onStart", &qu ...

  4. CentOS中vsftp安装、配置、卸载

    1. 安装VSFTP 1 [root@localhost ~]# yum -y install vsftpd 2. 配置vsftpd.conf文件 [root@localhost ~]# vi /et ...

  5. 基于jQuery 的图片瀑布流实现

    解题思路: 第1步  分析问题:我这边的处理方式是以列为单位.每次滚动条滚到底部,把需要加的新的内容放在高度最小的列.如下图所示 加载后的显示 如果在继续往下滚动.新图片就会在1下边显示,如此类推. ...

  6. 浅谈Chrome V8引擎中的垃圾回收机制

    垃圾回收器 JavaScript的垃圾回收器 JavaScript使用垃圾回收机制来自动管理内存.垃圾回收是一把双刃剑,其好处是可以大幅简化程序的内存管理代码,降低程序员的负担,减少因 长时间运转而带 ...

  7. GlusterFS简单配置

    1.准备工作 准备三台机器(物理机或者虚拟机均可)用于安装和测试GlusterFS,其中两台用作服务器,一台用作客户端,主机名分别为: Server1.zhaogang.int  10.0.21.24 ...

  8. SSI指令教程

    一:概述 SSI:服务器端嵌入或者叫服务器端包含,是Server Side Include的简写.SSI技术通过在文档中加入SSI指令,让服务器端在输出文档之前解析SSI指令,并把解析完的结果和文档一 ...

  9. iscc2016-好长的字符串

    Vm0wd2QyVkhVWGhVYmxKV1YwZDRXRmxVUm5kVlJscHpXa2M1VjFKdGVGWlZNbmhQWVd4YWMxZHViRmROYWxaeVdWZDRZV014WkhG ...

  10. xml格式化写入文件

    参考xml文件地址:http://cloudprint.cainiao.com/template/standard/101 代码: package main import ( "encodi ...