有关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 ...
随机推荐
- Shell数值比较
Shell数值比较 比较 描述 n1 -eq n2 检查n1是否与n2相等 n1 -ge n2 检查n1是否大于或等于n2 n1 -gt n2 检查n1是否大于n2 n1 -le n2 检查n1是否小 ...
- python 03 8/25-8/27 range 、randint
import random """字符串的操作中 三种方法,只包含左索引,不包含右索引""" hi= "bokeyuan pyth ...
- Java Web中的编码解析
在springmvc工程web.xml中配置中文编码 <!-- 配置请求过滤器,编码格式设为UTF-8,避免中文乱码--> <filter> <filter-name&g ...
- Python爬虫-Scrapy-CrawlSpider与ItemLoader
一.CrawlSpider 根据官方文档可以了解到, 虽然对于特定的网页来说不一定是最好的选择, 但是 CrwalSpider 是爬取规整的网页时最常用的 spider, 而且有很好的可塑性. 除了继 ...
- UVA - 10410 Tree Reconstruction (根据dfs序和bfs序恢复一颗树)
题意: 分析: 这题一开始完全没有思路, 一直没有找出规律. 参考了http://www.cnblogs.com/Wade-/p/6358859.html 和 http://www.cnblogs.c ...
- 谷歌浏览器修改CSS和js后同步保存到文件中 (译)
本文标题:谷歌浏览器修改CSS和js后同步保存到文件中. 文本作者:魔芋铃. 英文原文:http://www.stephensaw.me/google-chrome-devtools-source-m ...
- CEF与代理
此文已由作者王荣涛授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. CEF(Chromium Embedded Framework)如今已经广泛被应用于客户端软件,网易内部就有 ...
- cherrypy & gevent patch
给cherrypy 打gevent WSGIServer的patch 1. patch Serving 类 2. 关闭python的原生WSGIServer 具体使用例子参考 我的开源项目 http ...
- 【NOIP模拟】数字对(RMQ,二分)
题意:小H是个善于思考的学生,现在她又在思考一个有关序列的问题. 她的面前浮现出一个长度为n的序列{ai},她想找出一段区间[L, R](1 <= L <= R <= n). 这个特 ...
- C++,C程序设计入门——《高质量程序设计第4章》
1. 连接规范 1. extern “C” 2. 一部分采用C的连接规范 #ifdef __cplusplus extern "C" { #endif #ifdef __cplus ...