- 浏览: 155042 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
西巴拉古呀那:
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 888转自:http://blog.csdn.net/chen7 ... -
阻塞同步synchronized
2013-05-03 08:40 1224转自:http://blog.csdn.net/chen7 ... -
关于中断处理
2013-05-03 08:41 853在历史上,Java试图提供过抢占式限制中断,但问题多多,例如前 ... -
wait和notify机制
2014-03-03 13:47 961Wait-Notify机制可以说是实现阻塞操作较为高效的一 ... -
lock和lockInterruptibly
2014-03-03 13:47 5212lockInterruptibly()允许在等待时由其他线程 ... -
流io 读
2014-03-03 13:47 6441. 关于InputStream.read() ... -
设计模式之不变模式(Immutable Pattern)分析
2014-03-06 10:55 790主要介绍编写不变类的主意事项: 归纳一下设计不变类的 5 ... -
jvm参数
2014-03-03 13:47 593作者:Ken Wu Email: ken.wu ... -
jvm参数配置
2014-03-03 13:48 553/usr/local/jdk/bin/java -D ... -
读取Properties文件的六种方法
2014-03-14 10:11 6781。使用java.util.Properties类的load ... -
从Java视角理解伪共享(False Sharing)
2014-03-14 10:11 697从Java视角理解系统结构 ... -
从Java视角理解CPU缓存(CPU Cache)
2014-03-14 10:11 1128从Java视角理解系统结构 ... -
从Java视角理解CPU上下文切换(Context Switch)
2014-03-16 10:52 1679从Java视角理解系统结 ... -
浅谈JAVA ThreadPoolExecutor
2014-03-12 09:37 892基础 在我看来,java比C++的一个大好处就是提供了对 ... -
Java多线程同步如何从JVM的角度体会
2014-03-18 20:20 769我们在使用Java多线程 ... -
java 安全沙箱模型
2012-02-22 21:15 787起到第一道安全保障作 ... -
单个进程最大线程数
2012-01-10 10:09 28729原文链接:http://jzhihui.iteye.com/b ... -
jvm的线程创建
2012-01-09 13:48 3977在操作系统中,有两种不同的方法提供线程支持:用户层的用户线程, ... -
简单的路径使用(转)
2011-12-03 11:38 718用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还 ...
相关推荐
提示Initialization failure-0x0000000c错误无法上网怎么办.docx
dm00104712-stm32cubemx-for-stm32-configuration-and-initialization-c-code-generation-stmicroelectronics.pdf
we build on the initialization method proposed by Martinelli [1] and extended by Kaiser et al. [2], modifying it to be more general and efficient. We improve accuracy with several rounds of visual-...
文档详细说明了BIOS阶段的加载流程,PCI各地址段的映射,对于了解PCI设备在bios阶段如何映射到系统非常有用。
SubarnaTripathi-Tracker_Initialization-
对象初始化实验室 目标 用自定义的初始化例程定义一个类。 从初始化设置实例变量属性。 为初始化参数包括默认参数。 概述 您将要构建一个Person类,该类在初始化一个人时接受一个人的名字。 您还将要构建一个Dog类...
Linux 2.4.x Initialization for IA-32Linux 2.4.x Initialization for IA-32
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 ...
平台初始化自我认证测试(pi-sct)项目提供了在平台上练习界面的来源,并通过UEFI uefi.org上的PI Spec对PEI和DXE基础进行了特定测试,以验证与PI规范的兼容性。
SetConsole是用于Linux平台上的文本模式控制台初始化的脚本。 它为每个控制台设置字体,应用程序字符映射,光标,键盘LED以及许多其他设置。
介绍了DAVE环境下XMC1000的启动文件;本应用文档是英飞凌官方提供的介绍XMC1000的启动过程和器件初始化的文档;对英飞凌单片机器件底层驱动文件提供了更深刻的了解!
适用于Linux的iSCSI-init引导初始化程序
初始化Initialization初始化Initialization初始化Initialization
FWInit是一个简单的防火墙初始化实用程序,使用Python配置脚本用Python编码,可以使用有用的函数来操纵iptables过滤器并在两次调用之间保持相同的状态。
ora-01033:oracle initialization or shutdown in progress 解决方法 ora-01033:oracle initialization or shutdown in progress 解决方法 ora-01033:oracle initialization or shutdown in progress 解决方法 ora-...
2014-10-14 10:10:21.409 WARN 3435 --- [ main] o.s.b.a.jdbc.DataSourceInitializer : Could not send event to complete DataSource initialization (ApplicationEventMulticaster not initialized - call ' ...
Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and ...
数组初始化vi清华大学精通LabVIEW虚拟仪器程序设计光盘
Whether you're an experienced C programmer or you're coming from a different language such as C++ or Java, leading Mac experts Scott Knaster and Waqar Malik show how to harness the power of Objective-...
Overrides the standard java.lang.Object.clone method to return a copy of this cookie. containsHeader(String) - Method in class javax.servlet.http.HttpServletResponseWrapper The default behavior of ...