有关java构造器的笔记
当程序中首次出现使用一个类A时, 无论是使用A的静态成员还是创建一个对象(声明一个A类对象不算), 那么类加载器就会首先对A进行加载, 在对A进行加载的过程中, 如果A有一个extends的父类B, 那么就先对这个B类进行加载, 如果B类还有父类, 就再加载B的父类,就这样层层向上加载, 直到加载Object基类为止,每个类在加载过程中完成了对该类的静态成员的默认初始化. 当Object类加载完成后, 就从Object类开始依次向下进行静态初始化直到A类, 然后执行A的静态初始化, 此时执行的静态初始化只伴随着类加载执行这一次, 执行之后就再也不执行了. 所谓默认初始化就是将基本数据类型初始化为0, 引用数据类型初始化为null. 静态初始化是按照静态变量和静态代码块的初始化顺序和声明顺序一致这一准则进行指定初始化.
然后如果使用的是new A a()(也就是实例初始化) , 就会为对象分配存储空间, 首先将这片存储空间清零(所谓清零就是对所有的非静态成员变量进行默认初始化), 然后开始执行A的构造函数, 无论是否明确的使用了super()调用A父类的构造函数, 都会在真正执行A的构造函数之前创建A的父类对象, 然后返回A的构造函数, 此时也并非开始执行构造函数内的程序, 而是对A的成员变量进行指定初始化, 初始化的顺序和静态指定初始化的顺序一致, 最后执行A的构造函数内的程序, 完成初始化
当初始化涉及多态时, 如果父类的非静态代码块或者父类的构造函数中调用了涉及到多态的函数, 那么这个函数是A类相应重写的函数.
class Glyph
{
{
draw() ; //会调用子类的
} void draw()
{
System.out.println("Glyph draw()") ;
} public Glyph()
{
System.out.println("Glyph() before draw()") ;
draw(); //会调用子类的
System.out.println("Glyph() after draw()") ;
}
} public class RoundGroph extends Glyph
{
private int radius = 1 ;
RoundGroph(int i)
{
radius = i ;
System.out.println("RoundGroph.Grougph().radius= " + radius) ;
} void draw()
{
System.out.println("RoundGroph.draw().radius= " + radius) ;
} public static void main(String args[])
{
RoundGroph a = new RoundGroph(22) ;
}
}
之所以会出现这种情况是因为 动态绑定 . java之所以有多态, 就是由于动态绑定.
这个是有关动态绑定的一片非常好的文章:http://www.cnblogs.com/yyyyy5101/archive/2011/08/02/2125324.html
上述代码就是对《thinking in java》这段话的一个解释
如果构造器只是在构建对象的一个步骤,并且 该对象所属的类 是从 这个构造函数所属的类 导出的,那么导出部分在当前构造器正在被调用的时刻仍然是没有初始化的。然而一个动态绑定的方法调用却会深入到继承层次结构的内部,调用导出类的方法。如果我们在构造函数中这么做,那么就可能调用某个方法,而这个方法所使用的成员可能还尚未初始化--这肯定会招灾引祸。
上面代码中的RoundGroph是Glyph的子类。按照上面对于有继承关系的初始化过程的描述,当遇到new RoundGroph(22),就会分配存储空间,并对RoundGroph的成员进行默认初始化,然后初始化他所持有的RoundGroph对象,在初始化Glyph的过程中会调用draw(),这个方法是动态绑定的,在RoundGroph还未完全初始化的情况下调用RoundGroph的draw(),如果此时draw()中使用了未初始化的子类成员变量,那么就会导致莫名的错误,也就是《thingking in java》中所说的招灾引祸。
因此,最好不要在构造器中调用函数, 在构造器中唯一能够安全调用的就是private 或 final函数, 如果一定要调用带有动态绑定的函数, 就一定要非常小心了.
//thinking in java笔记,如果有不对的地方,还望指正^_^
有关java构造器的笔记的更多相关文章
- java 构造器学习笔记
构造器(构造器不是方法也不是类的成员) 以前创建对象的方式, public class Constructor{ public static void main(String[] args){ per ...
- java effective 读书笔记
java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 si ...
- 《Thinking In Java》阅读笔记
<Thinking In Java>阅读笔记 前四章:对象导论. 一切都是对象. 操作符. 控制执行流程 public在一个文件中只能有一个,可以是一个类class或者一个接口interf ...
- Java NIO 学习笔记(五)----路径、文件和管道 Path/Files/Pipe
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- 尚学堂JAVA基础学习笔记
目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...
- JAVA Web学习笔记
JAVA Web学习笔记 1.JSP (java服务器页面) 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . JSP全名为Java Server Pages,中文名叫java服务器 ...
- Java编程思想 笔记
date: 2019-09-06 15:10:00 updated: 2019-09-24 08:30:00 Java编程思想 笔记 1. 四类访问权限修饰词 \ 类内部 本包 子类 其他包 publ ...
- Kotlin for Java Developers 学习笔记
Kotlin for Java Developers 学习笔记 ★ Coursera 课程 Kotlin for Java Developers(由 JetBrains 提供)的学习笔记 " ...
- Java IO学习笔记七:多路复用从单线程到多线程
作者:Grey 原文地址:Java IO学习笔记七:多路复用从单线程到多线程 在前面提到的多路复用的服务端代码中, 我们在处理读数据的同时,也处理了写事件: public void readHandl ...
随机推荐
- css控制超出部分自动省略...
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 【简●解】POJ 1185,LG P2704【炮兵阵地】
POJ 1185,LG P2704[炮兵阵地] 状压经典入门. [传送门] POJ 1185 洛谷 P2704 [题目大意] 司令部的将军们打算在 \(N\times M\) 的网格地图上部署他们的炮 ...
- 关于C/C++的一些思考(5)
运算符重载函数的限制: 五个不能实现重载的符号:".", ".*", "::", "?", "sizeof&q ...
- HTML5表单新增元素与属性
form属性 在html4中,表单的从属元素必须写在表单内部,而在HTML5中,可以把他们书写在任何地方,然后为该元素指定一个form属性,属性值为该表单的id,这样就可以声明该元素从属于指定表单了. ...
- fshc模块fsch2mcu_if理解
fshc2mcu_if中包括ahb2reg/ahb2fifo两个文件,都是协议转换文件.ahb2reg下游文件是reg files,ahb2fifo下游文件是fifo控制器.所有的配置和flag都是要 ...
- javax.servlet.jsp.JspTagException: Neither BindingResult nor plain target object for bean (蛋疼死我了)
1为抛出异常原因,2为异常解决方法. 原因: 进入spring:bind标签源码你可以看到 Object target = requestContext.getModelObject(beanNa ...
- Android开发——查询/杀死手机里正在运行的进程
0. 前言 以前有同学好像做过一个叫"自习君"的App,开启后自动检测用户这一天的自习时间,在学校里宣传广告还打了不少.其实实现原理非常简单,在SQlite数据库(也可以通过文件) ...
- 洛谷 P1938 [USACO09NOV] 找工就业Job Hunt
这道题可以说是一个复活SPFA的题 因为数据比较小,SPFA也比较简单 那就复习(复读)一次SPFA吧 #include<iostream> #include<cstdio> ...
- Oracle数据库之初步接触
每个Oracle数据库都是数据的集合,这些数据包含在一个或多个文件中.数据库有物理和逻辑两种结构.在开发应用程序的过程中,会创建诸如表和索引这样的结构,这些结构用于数据行的存储和查询.可以为对象的名称 ...
- 洛谷 P3800 Power收集
题目背景 据说在红雾异变时,博丽灵梦单身前往红魔馆,用十分强硬的手段将事件解决了. 然而当时灵梦在Power达到MAX之前,不具有“上线收点”的能力,所以她想要知道她能收集多少P点,然而这个问题她答不 ...