[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 ...
随机推荐
- redis 多实例配置
(redis的安装, 配置, 登陆等基础不再多说, 网上很多资料的, 这里只说个人对redis多实例的理解与配置) 我自己使用的redis版本是 2.8.13, 环境是 ubuntu 个人对多实例的理 ...
- poj 1811 Pallor Rho +Miller Rabin
/* 题目:给出一个数 如果是prime 输出prime 否则输出他的最小质因子 Miller Rabin +Poller Rho 大素数判定+大数找质因子 后面这个算法嘛 基于Birthday Pa ...
- ASP.NET-FineUI开发实践-13(一)
开原版好像是没有gird树,有一个扩展列下的模拟树列,就是不能展开,专业版有,开原版我弄了弄,思路是有,就是不是很好实现.这篇博客直接写出了(一)说明一个肯定是写不完的. FineUI重在封装,改这个 ...
- (转)PHP函数spl_autoload_register()用法和__autoload()介绍
转--http://www.jb51.net/article/29624.htm 又是框架冲突导致__autoload()失效,用spl_autoload_register()重构一下,问题解决 ...
- linux list all users.
cat /etc/passwd sample of list users in linux. ref: Linux Command: List All Users In The System
- JavaScript--Date函数
1. Date函数 var now = new Date(); 获取当前日期对象 now对象->Date.prototype->Object.prototype 将一个字符串转换为Date ...
- createElement()结合appendChild()的实例
createElement()作用是在JavaScript中创建一个元素 appendChild()向html元素添加节点 下面是冲浪后改编的例子代码 先插html代码 <body> &l ...
- jQuery1.6以上版本prop和attr的区别
- C语言笔记(结构体与offsetof、container_of之前的关系)
关于结构体学习,需要了解:结构体的定义和使用.内存对齐.结构体指针.得到结构体元素的偏移量(offsetof宏实现) 一.复习结构体的基本定义和使用 typedef struct mystruct { ...
- git的使用说明详解
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/001375840202368c7 ...