- 浏览: 159650 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
西巴拉古呀那:
Linux多线程并发服务器编程(线程池,FTP服务器)网盘地址 ...
多线程服务器的适用场合 -
somefuture:
第四题怎麼用位图法。写了半天没出来,用了下面的,速度很快pri ...
位图法应用 -
寂寞秋江:
系统,全面,条理清晰,由浅入深,简直是集大成之作。 特别是最后 ...
单个进程最大线程数 -
darkjune:
有点意思, 不错
单个进程最大线程数 -
kidding87:
谢谢啦,收藏着
google使用一点敲门分享
转自:http://www.danielschneller.com/2010/07/java-object-initialization-order-know.html
Recently I came across an interesting problem whose solution eluded me at first glance. Consider these three classes:
package com.ds.test; public class Upper { String upperString; public Upper() { Initializer.initialize(this); } }
package com.ds.test; public class Lower extends Upper { String lowerString = null; public Lower() { super(); System.out.println("Upper: " + upperString); System.out.println("Lower: " + lowerString); } public static void main(final String[] args) { new Lower(); } }
package com.ds.test; public class Initializer { static void initialize(final Upper anUpper) { if (anUpper instanceof Lower) { Lower lower = (Lower) anUpper; lower.lowerString = "lowerInited"; } anUpper.upperString = "upperInited"; } }
What output is to be expected from running the Lower
class?
In this very reduced example it is much easier to
get a view of the whole situation - in reality where this occurred there was a
lot more code to distract one's attention...
Anyway, this is what the output
looks like:
Upper: upperInited Lower: null;
While the little example uses Strings, the real code of
Initializer
had a delegate object registered with the equivalent of
the Lower
class - at least that was the intention. For some reason
however did this not work when running the application. Instead, the default
path was taken - the one for the delegate object being not set
(null
).
Now, change the code of Lower
slightly:
package com.ds.test; public class Lower extends Upper { String lowerString; public Lower() { super(); System.out.println("Upper: " + upperString); System.out.println("Lower: " + lowerString); } public static void main(final String[] args) { new Lower(); } }
The output is now:
Upper: upperInited Lower: lowerInited
Notice the difference in the code?
Yes, the lowerString
field is no longer explicitly set to null
. Why would this make a
difference? Isn't the default value for reference type fields (such as
String
here) null
anyway? Of course, it is. However it
turns out that this tiny little change - which apparently would not change the
code's behavior in any way - makes this thing fly or not fly.
So what is
going on? It becomes clear when looking at the initialization order:
-
main()
calls theLower
constructor. - An instance of
Lower
is prepared. That means, all fields are created and populated with default values, i. e.null
for reference types,false
forboolean
s and so on. At this time, any inline assignments to the fields have not taken place! - The super-constructor is called. This is mandated by the language spec. So,
before anything else happens,
Upper
's constructor is called. - The
Upper
constructor runs and hands a reference to the freshly created instance to theInitializer.initialize()
method. - The
Initializer
attaches newString
s to both fields. It does so by using a somewhat dirtyinstanceof
check - not a particularly good design pattern, but possible, nevertheless. Once that has happened, both theupperString
lowerString
references are no longernull
. - The
Initializer.initialize()
call finishes, as does theUpper
constructor. - Now it becomes interesting: Construction of the
Lower
instance continues. Assuming there is no explicit=null
assignment in thelowerString
field declaration, theLower
constructor resumes execution and prints out the two Strings that are attached to the fields.
However, if there is an explicit assignment tonull
, execution has a slightly different flow: Just after the super constructor is done, any variable initializers are executed (see section 12.5 of the Java Language Spec), before the rest of the constructor is run. In this case theString
reference that was previously assigned tolowerString
is now overwritten withnull
again! Only then does the rest of the constructor continue execution, now printinglowerString: null
.
Apart from being a nice example for
why it is handy to be aware of some of the minutiae of object creation (or
knowing where to look in the JLS, printed or online) this shows why it is a bad
idea to write the Initializer
like this. It should not be aware of
Upper
's subclasses at all! Instead, if for some reason
initialization of certain fields cannot be done in the Lower
class
itself, it will just require its own variant of some sort of initialization
helper. In that case, it would really make no difference if you used
String lowerString;
or String lowerString = null;
-
just as it should be.
发表评论
-
阻塞同步 lock
2013-05-03 08:39 931转自:http://blog.csdn.net/chen7 ... -
阻塞同步synchronized
2013-05-03 08:40 1273转自:http://blog.csdn.net/chen7 ... -
关于中断处理
2013-05-03 08:41 885在历史上,Java试图提供过抢占式限制中断,但问题多多,例如前 ... -
wait和notify机制
2014-03-03 13:47 1034Wait-Notify机制可以说是实现阻塞操作较为高效的一 ... -
lock和lockInterruptibly
2014-03-03 13:47 5268lockInterruptibly()允许在等待时由其他线程 ... -
流io 读
2014-03-03 13:47 6731. 关于InputStream.read() ... -
设计模式之不变模式(Immutable Pattern)分析
2014-03-06 10:55 844主要介绍编写不变类的主意事项: 归纳一下设计不变类的 5 ... -
jvm参数
2014-03-03 13:47 629作者:Ken Wu Email: ken.wu ... -
jvm参数配置
2014-03-03 13:48 593/usr/local/jdk/bin/java -D ... -
读取Properties文件的六种方法
2014-03-14 10:11 7261。使用java.util.Properties类的load ... -
从Java视角理解伪共享(False Sharing)
2014-03-14 10:11 739从Java视角理解系统结构 ... -
从Java视角理解CPU缓存(CPU Cache)
2014-03-14 10:11 1191从Java视角理解系统结构 ... -
从Java视角理解CPU上下文切换(Context Switch)
2014-03-16 10:52 1719从Java视角理解系统结 ... -
浅谈JAVA ThreadPoolExecutor
2014-03-12 09:37 931基础 在我看来,java比C++的一个大好处就是提供了对 ... -
Java多线程同步如何从JVM的角度体会
2014-03-18 20:20 793我们在使用Java多线程 ... -
java 安全沙箱模型
2012-02-22 21:15 819起到第一道安全保障作 ... -
单个进程最大线程数
2012-01-10 10:09 28841原文链接:http://jzhihui.iteye.com/b ... -
jvm的线程创建
2012-01-09 13:48 4035在操作系统中,有两种不同的方法提供线程支持:用户层的用户线程, ... -
简单的路径使用(转)
2011-12-03 11:38 745用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还 ...
相关推荐
项目中碰到的问题
### Java - The Well-Grounded Java Developer #### PART 1: DEVELOPING WITH JAVA 7 **1. Introducing Java 7** - **Overview**: This section provides a comprehensive introduction to the new features and ...
"解决 Initialization failure: 0x0000000c 错误无法上网的多种方法" 在本文中,我们将讨论 Initialization failure: 0x0000000c 错误的多种解决方法,这个错误通常会导致无法上网的情况。本文将从问题的根源开始,...
在Java编程语言中,设计模式是一种经过验证的解决常见软件设计问题的最佳实践。单例模式是其中最常用的一种,它的核心思想是确保一个类只有一个实例,并提供全局访问点。单例模式的应用场景包括:控制资源的访问、...
在计算机硬件领域,PCI(Peripheral Component Interconnect)系统地址映射初始化是一个至关重要的步骤,它涉及到BIOS(基本输入输出系统)在启动过程中如何管理和分配系统内存资源给PCI设备。本文将深入探讨PCI设备...
对象初始化实验室 目标 用自定义的初始化例程定义一个类。 从初始化设置实例变量属性。 为初始化参数包括默认参数。 概述 您将要构建一个Person类,该类在初始化一个人时接受一个人的名字。 您还将要构建一个Dog类...
Java虚拟机(JVM)的类加载过程是Java程序运行的基础,它涉及到类加载器、类的生命周期和一系列复杂的步骤。在这个过程中,类加载器主要任务是根据类的全限定名加载二进制字节流并转化为`java.lang.Class`对象。整个...
标题中的"Console Initialization script-开源"指的是一个专用于Linux系统的脚本,它的主要功能是对文本模式的控制台进行初始化设置。这个脚本被称为"SetConsole",它在系统启动时运行,确保控制台具备合适的配置,...
【标题】"SubarnaTripathi-Tracker_Initialization-" 暗示了这是一个与追踪算法初始化相关的项目,可能是一个研究或教程,由Subarna Tripathi主导。在计算机视觉和机器学习领域,追踪器初始化是目标追踪过程中的关键...
Java基础是学习任何Java开发者的基石,而数组作为Java中最基本的数据结构,是理解内存管理的关键。本节我们将深入探讨“Java基础中的数组与内存图解”,了解数组在内存中的存储方式及其工作原理。 首先,数组是Java...
automatic initialization to prevent another class of bugs. Chapter ten introduces delegates and shows how classes and callback functions cooperate to simplify, for example, the constant chore of ...
文档《Infineon-XMC1000-C_Start_and_Device_Initialization-AN-v01_00-EN启动文件说明.pdf》详细介绍了在DAVE开发环境中,如何进行XMC1000系列微控制器的启动文件配置与设备初始化。下面将围绕文档内容,展开对于...
平台初始化自我认证测试(Platform Initialization Self Certification Test,简称pi-sct)是一个开源项目,它为IT专业人士提供了一个工具,用于测试和验证平台的初始化过程是否符合UEFI(统一可扩展固件接口)标准...
Java企业版(Enterprise JavaBeans,EJB)是Java平台中用于构建可扩展、安全和事务处理的服务器端应用程序的关键技术。这个"基于Java的实例源码-各种EJB之间的调用示例.zip"压缩包提供了关于如何在Java环境中实现EJB...
在`Cupboard.java`、`StaticInitialization.java`、`Table.java`和`Bowl.java`这些文件中,我们可以看到不同类的定义,如`Cupboard`、`StaticInitialization`、`Table`和`Bowl`。 2. **实例化(Instantiation)**:...
"Array-Initialization-.zip" 文件可能是一个教学资源,专为帮助用户掌握在LabVIEW中如何初始化和操作数组而设计。在这个实验室练习中,"Array Initialization .vi" 可能是一个虚拟仪器(VI)示例,演示了数组的创建...
Java编程语言中的错误和最佳实践在面试中是常见的考察点,尤其对于Java程序员而言,理解并掌握这些知识点至关重要。以下是一些从提供的文档内容中提取的关键知识点及其详细解释: 1. **抽象方法(Abstract Methods...
Java面试中的代码与编程问题涵盖了广泛的Java编程概念,包括设计模式、类的初始化以及内部类的使用。以下是对这些问题的详细解释: 1. **Singleton模式**:Singleton模式是一种设计模式,确保一个类只有一个实例,...
Linux iSCSI Boot Initialization Program,通常被称为iSCSI-init,是一种开源软件,专门设计用于Linux操作系统,以实现通过网络启动(Network Booting)系统。它允许计算机通过Internet SCSI(iSCSI)协议从远程...