【发布时间】:2013-05-20 15:31:48
【问题描述】:
我曾经认为,直观地说,Java 中的构造函数是生成对象的东西,在构造函数返回之前,没有任何东西可以触及该对象。然而,我一次又一次地被证明是错误的:
- 共享
this会泄露未初始化的对象 - uninitialized objects can be leaked by a subclass accessing it from the finalizer
- uninitialized objects can be leaked to another thread before they're fully constructed
所有这些事实都违背了我对构造函数的直觉。
我不能再自信地说构造函数在 Java 中的实际作用,或者它的用途。如果我用所有最终字段制作一个简单的DTO,那么我可以理解构造函数的用途,因为这与C中的结构完全相同,只是它不能被修改.除此之外,我不知道在 Java 中可以可靠地使用哪些构造函数。它们只是约定/语法糖吗? (即,如果只有工厂为您初始化对象,您将只有 X x = new X(),然后修改 x 中的每个字段以使其具有非默认值 - 鉴于上述 3 个事实,这几乎等同于如何Java实际上是)
我可以命名两个实际上由构造函数保证的属性:如果我这样做X x = new X(),那么我知道x 是X 的一个实例,但不是X 的子类,它的最终字段是完全初始化。您可能想说您知道 X 的构造函数已完成并且您拥有一个有效对象,但如果您将 X 传递给另一个线程 - the other thread may see the uninitialized version(即您刚才所说的与调用工厂的保证)。构造函数实际上还保证了哪些其他属性?
【问题讨论】:
-
@Dog - 你能在java中创建一个不使用对象构造函数的工厂吗? (使用 sun.misc.Unsafe 不算在内)。
-
@jtahlborn 这不公平。
-
您观察到的构造函数可能构造不正确。
-
@jtahlborn 对不起队友,这是灰色区域,你可以避免构造函数。反射和克隆就是几个例子
-
@Raza - 反射并不能避免构造函数。克隆和序列化避免了构造函数,但这并没有使它成为“灰色区域”。您只能克隆和序列化现有实例,因此,您仍然需要一个构造函数(用于现有实例)。
标签: java security inheritance concurrency constructor