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,如何精炼,如此有趣。值得一看。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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 静态_非静态 字段_方法_代码块 子类父类构造_初始化顺序! 三个class 让你清清楚楚 第一个class java代码如下: package initialOrder; class Parent { // 静态变量 public static String p_StaticField...
2. **构造器与初始化**:子类对象在创建时会先调用父类的构造器,确保父类的状态得到正确初始化,然后执行子类自己的构造逻辑。 3. **变量隐藏**:如果子类和父类有同名的实例变量,子类变量会“隐藏”父类变量。...
这个顺序对于理解类的初始化过程非常重要,特别是在处理复杂的继承结构时,可能包含多个父类和多个子类的构造器,以及静态和非静态初始化块。确保理解这个顺序可以帮助避免潜在的运行时错误,例如,依赖于未初始化的...
本文将详细探讨Java中类的初始化过程及其顺序,并通过具体的代码示例来帮助理解这一过程。 #### 二、基础知识 1. **静态成员变量(Static Fields)**:在类加载时初始化。 2. **实例成员变量(Instance Fields)**...
Java中的对象初始化流程是编程实践中一个非常重要的概念,它涉及到类加载、静态初始化块、实例初始化块、构造器等多个方面。下面将详细解释这个过程。 首先,对象初始化流程的起点是程序的入口点,即`main`方法。当...
Java 对象初始化顺序是指在 Java 程序中,对象的初始化过程中发生的顺序问题。这是 Java 编程语言的基础知识点之一,但是许多学生在学习和使用时总是感到困惑和困难。 二、JVM 执行过程中的“礼让”原则 JVM 在...
这是Java语言规范所规定的,确保在子类访问父类的静态或非静态成员时,父类的初始化已经完成。 在实际开发中,理解这个初始化顺序是非常重要的,尤其是在设计复杂的类结构或者涉及单例模式、线程安全初始化等场景时...
当创建一个子类实例时,初始化过程遵循以下步骤: 1. **静态初始化**:首先,执行父类的静态初始化块,然后执行子类的静态初始化块。静态初始化块用于初始化类级别的静态变量,它们只在类加载时执行一次。 2. **...
这个"java代码的初始化顺序demo"显然旨在演示这一过程。让我们深入探讨Java中的初始化顺序及其背后的机制。 1. **类加载阶段**: 在Java程序运行时,JVM会先加载类的字节码文件(.class文件)。这个过程包括加载、...
在Java编程语言中,面向对象编程是核心特性之一。...同时,子类对象实例化的过程是先执行父类构造器,再执行子类构造器,保证了对象初始化的顺序。理解和掌握这些概念对于编写高效的Java代码至关重要。
- 当多个线程同时尝试初始化同一个类时,Java保证只会执行一次类的初始化过程。这是由JVM的同步机制保证的,避免了数据竞争的问题。 5. **接口初始化**: - 接口没有实例变量,所以不存在实例初始化阶段。接口的...
特别要注意的是,在子类的初始化过程中,子类的静态变量和静态初始化块会在父类的变量、初始化块、构造器之前就被初始化。也就是说,在父类完全初始化完毕之前,子类的静态成员已经完成初始化了。 这个顺序很重要,...
3. **子类初始化**: - 在父类初始化完成后,JVM开始处理子类的初始化。子类的非静态变量、初始化块和构造器会被执行。在这个例子中,子类的"SubClass--变量"、"SubClass--初始化块"和"SubClass--构造器"会在子类...
1. **静态成员和静态初始化块**:首先,会按照父类到子类的顺序初始化静态变量和执行静态初始化块。在上面的例子中,"父类 --静态变量" 和 "子类 --静态变量" 先被初始化,然后分别执行对应的静态初始化块。 2. **...
在Java编程世界中,类的初始化顺序是理解面向对象编程概念的一个重要方面。尤其对于那些准备应对技术面试的Java程序员和工程师来说,掌握这一知识点是面试时的必备能力之一。本文将深入探讨Java中类的初始化顺序,...
"Java子类对象的实例化过程分析" Java子类对象的实例化过程是Java面向对象程序设计中一个非常重要的概念。它涉及到Java类的继承、构造函数的调用、对象的实例化等多方面的知识。在这篇文章中,我们将详细介绍Java...
这对于初始化父类的状态非常有用。 - **追溯父类**:`super`不仅可以用于直接父类,还可以追溯到更远的祖先类。 **2. 调用父类构造器的语法** 在子类的构造方法中,可以使用以下语法调用父类的构造方法: ```java...
在Java编程语言中,对象初始化是一个关键的概念,它涉及到类加载、对象实例化以及成员变量的赋值。...在实际开发中,推荐使用构造器注入或者初始化方法来清晰地控制对象的初始化过程,以提高代码的可读性和可维护性。
本文详细介绍了类继承中的初始化顺序问题,包括初始化的基本概念、初始化过程中的关键步骤以及如何正确处理基类和子类之间的构造函数调用。理解这些概念对于编写高效、可维护的面向对象程序至关重要。希望通过对这些...