[Java] 实例创建的步骤
创建类的一个实例时,按照下面步骤进行创建:
1. 给当前类及其父、祖类的所有成员字段分配空间,并给它们赋予默认值
2. 开始执行当前类的构造器
3. 如果当前类有父类,则对父类创建一个实例:从第 2 步开始并把父类当作新的当前类
4. 给当前实例、当前实例的字段进行初始化
5. 执行当前类的构造器的剩余部分代码。
上面的步骤包含一个递归算法。假设类 C 有父类,实例化 C 到第 3 步的时候,需要先创建父类的一个实例,即父类要经历完第 2、3、4、5 步骤之后,才到类 C 继续第 4 步。如果父类也有自己的父类,则父类的父类也要先实例化,才到父类执行第 3 步。依次类推,直到实例化 Object 类,因为 Object 类没有父类。
下面有两个例子进行说明。
1,常规的类实例化
public class Point {
int x, y;
Point(){ x = 1; y = 1; }
}
public class ColoredPoint extends Point {
int color = 0xFF00FF;
}
public class InstanceDemo {
public static void main(){
ColoredPoint cp = new ColoredPoint();
System.out.println(cp.x + " | " + cp.y + " | " + cp.color);
}
}
引起创建类的实例的是代码 new ColoredPoint(),下面是实例创建的步骤:
1. 分配内存给字段 x, y, color, 并给他们赋予默认值
2. ColoredPoint 的构造器被调用
3. ColoredPoint 没有声明构造器,则调用其默认构造器:
ColoredPoint(){ super(); }
4. 上面的 super() 实际指的是 Point 的无参构造器。Point 的无参构造器最开始部分没有调用其他构造器,则 Java 编辑器提供插入了一个构造器调用,变成:
Point(){ super(); x = 1; y = 1; }
5. 上面的 super() 实际指的是 Object 的无参构造器。Object 没有父类,不会被插入构造器。Object 的无参构造器没有任何副作用或返回值。被调用的构造器如下
Object() { }
6. Point 的字段被初始化。在这里,字段 x, y 无需被初始化。
7. Point 的构造器被继续执行,即对 x , y 分别赋值为 1 。至此,父类 Point 实例化结束
8. ColoredPoint 的字段被初始化。在这里,字段 color 被初始化为 0xFF00FF。
9. ColoredPoint 的构造器被继续执行。在这里,没有其他代码在构造器里面,无需继续执行。至此,ColoredPoint 实例化结束。
2,动态调度在实例化期间的影响
Super,作为父类,在构造器中调用函数 printStatus()。注意,printStatus() 函数被子类重写,所以这里调用的不是 Super 自身的 PrintStatus(),而是其子类的 printStatus().
Sub, 继承于 Super 类,在构造器中调用 printStatus(),然后对变量 age 重写赋值。
InstanceDDDemo, 演示在实例化期间,方法动态调度的影响。
具体代码:
public class Super {
public Super(){
System.out.println("in Super() ");
printStatus();
}
public void printStatus(){
System.out.println("Super.printStatus - ");
}
}
public class Sub extends Super{
private int age = 10;
public Sub(){
System.out.println("in Sub() ");
printStatus();
age = 20;
}
public void printStatus(){
System.out.println("Sub.printStatus - " + age);
}
}
public class InstanceDDDemo {
public static void main(){
Sub point = new Sub();
System.out.println(" After instance ");
point.printStatus();
}
}
输出:
in Super()
Sub.printStatus - 0
in Sub()
Sub.printStatus - 10
After instance
Sub.printStatus - 20
从输出可见,在执行 Sub 构造里面的代码之前,Sub.printStatus() 已经被调用过一次。
Java 支持方法的动态调度。动态调度是指在运行时才决定选择哪一个多态实现方法。虽然 Super 有自己的 printStutus() 放方法,但是本例子中,Super 构造函数的调用,是由于它被 Sub 类继承,并且 Sub 类在被实例化,所以,这里最原始的目的是创建 Sub 类实例,而 printStutas() 方法对于 Sub 类来说已经被重写了,故在调用父类 Super 的构造器中仍然调用被重写后的 Sub.printStatus().
参考资料
12.5 Creation of New Class Instance, The Java Language Specification, Java SE 8 Edition
[Java] 实例创建的步骤的更多相关文章
- Java - 35 Java 实例
Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 Java 实例 – 如何编译一个Java 文件? Java 实 ...
- Java-Runoob-高级教程:Java 实例
ylbtech-Java-Runoob-高级教程:Java 实例 1.返回顶部 1. Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. ...
- Java 实例
Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 Java 实例 – 如何编译一个Java 文件? Java 实 ...
- Java 学习(21):Java 实例
Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 //HelloWorld.java 文件 public cla ...
- Thrift入门及Java实例演示<转载备用>
Thrift入门及Java实例演示 作者: Michael 日期: 年 月 日 •概述 •下载配置 •基本概念 .数据类型 .服务端编码基本步骤 .客户端编码基本步骤 .数据传输协议 •实例演示(ja ...
- Java线程创建形式 Thread构造详解 多线程中篇(五)
Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制. 创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象. 构造方法列表 ...
- Java中创建线程的三种方式以及区别
在java中如果要创建线程的话,一般有3种方法: 继承Thread类: 实现Runnable接口: 使用Callable和Future创建线程. 1. 继承Thread类 继承Thread类的话,必须 ...
- java工作流activiti的步骤
链接:activiti 表名称的解释 工作流从流程定义到创建一个流程实例完成执行步骤(省略bpmn的画法) 工作流的所有操作都是使用流程引擎来进行操作的,流程引擎只是存储流程的过程,而不存储具体的业务 ...
- Java开发工具安装步骤内容如下
Java开发工具安装步骤内容如下 安装 开发工具 STS 链接下载网址 eclipse 链接下载网址 JDK安装 jdk链接下载地址 Marven环境 marven链接下载地址 Tomcat tomc ...
随机推荐
- 模板-->Guass消元法(求解多元一次方程组)
如果有相应的OJ题目,欢迎同学们提供相应的链接 相关链接 所有模板的快速链接 简单的测试 None 代码模板 /* * TIME COMPLEXITY:O(n^3) * PARAMS: * a The ...
- Python多线程锁
[Python之旅]第六篇(四):Python多线程锁 python lock 多线程 多线程使用方法 多线程锁 摘要: 在多线程程序执行过程中,为什么需要给一些线程加锁以及如何加锁,下面就来 ...
- IOS 开发 【objective-c 基础1】
案例:读取本地硬盘上程序根目录下words.txt文件内容,显示每行的字符数. // // main.m // hello // // Created by swack on 15/11/27. // ...
- 生成PDF并下载。
例子是生成一个pdf格式的证书: //创建Document Document document = null; //为该Document创建一个Writer实例 PdfWriter writer = ...
- ASP.NET几种清除页面缓存的方法
在asp.net中使用模式dialog时,你会发现每次打开的页面都是相同的内容,页面内容并没有刷新,这是缓存的原因造成的, 解决方法如下: 第一种是ASP.NET清除页面缓存 Response.Buf ...
- List、Set、Map的使用
1.List(接口) List接口的特点: a.List接口可以存放任意数据,且在接口中,数据可以重复. b.List中提供了高效的插入和移除多个元素的方法. List常用的子类 a.ArrayLis ...
- c#结构体和字节数组的转换、字节数组和stream的转换
本文由博主(YinaPan)原创,转载请注明出处:http://www.cnblogs.com/YinaPan/p/streambytsstruct.html using System; using ...
- [转载] extern "C"的用法解析
本文转载自: http://www.cnblogs.com/rollenholt/archive/2012/03/20/2409046.html 1.引言 C++语言的创建初衷是“a better ...
- C++封装常用对象和对头文件探索
在C++实际开发中,难免会使用到一些你极为常用的算法(比如笔者经常使用的多线程技术),实现这些算法的类或是全局函数或是命名空间等等经常都要被使用多次,你会有哪些办法来使用呢?笔者有4个办法. 第一个方 ...
- Java反射机制(转载)
原文链接:http://www.blogjava.net/zh-weir/archive/2011/03/26/347063.html Java反射机制是Java语言被视为准动态语言的关键性质.Jav ...