Java 构造函数 return 是否已经存在相同类型的对象?

Can a Java constructor return already existing object of same type?

每当我们在 Java 中调用构造函数时,它都会创建一个新对象,并 return 在最后引用它(新创建的对象)。

是否有可能 Java 构造函数不创建新对象而是 return 对已创建对象的引用?

// Is it possible that myObject is not a new object, its already existing object
MyClass myObject = new MyClass();

我有一些 class 的对象列表,基于构造函数中的几个参数,有时我不创建新对象而是选择一个已经存在的对象会更有效。还有其他办法吗?

没有。构造函数定义 运行 当创建一个新对象时对其进行初始化。如果构造函数是运行,一个新的对象已经存在,你无能为力

你可以做的是创建一个静态方法,它可以创建一个新对象,或者 return 一个现有的对象。这是这种情况下的标准方法。

比如说,Boolean.valueOf(boolean value)在标准库中的存在是为了避免创建额外的对象。您可以使用 new Boolean(value) 创建它们,但最好调用此方法,因为它将 return 相同对象的相同值。

不,这不可能。

JLS section 15.9:

Unqualified class instance creation expressions begin with the keyword new.

An unqualified class instance creation expression may be used to create an instance of a class, regardless of whether the class is a top level (§7.6), member (§8.5, §9.5), local (§14.3), or anonymous class (§15.9.5).

JLS section 12.5:

A new class instance is explicitly created when evaluation of a class instance creation expression (§15.9) causes a class to be instantiated.
...
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure: [...]

请注意,这清楚地提到了对象的创建,而不是可能的 re-utilization。


另一方面,您可以为使用池的对象创建一个静态工厂。你可以看看 Integer.valueOf(i) for example. Refer to this answer for example.

的实现

你不能使用构造函数来做到这一点,但你可以使用下面提到的模式之一。

如果您只需要 1 个对象,则使用 Singleton 模式。

如果您可能有一些变化,请使用 Flyweight 模式,如 duffymo 所述。

正如 duffymo 在他下面的评论中提到的那样 - 如果您使用这些模式中的任何一个,那么从并发的角度来看,了解这些对象将是全局状态很重要 - 因此您应该确保它们是不可变的,如果您不能它们是不可变的,那么您可能需要重新考虑您的方法。

您无法仅使用 Java 中的构造函数实现此目的。

如果需要,可以通过使用 class 内部的静态方法(如 Integer.valueOf(0))或不同 class 的整个专用对象(如 DocumentBuilderFactory) 到 return 个实例。这提供了足够的控制来替换现有对象,而不是总是创建一个新对象。

通常,此类对象应该是不可变的和线程安全的,以便于共享。此外,实例重用和有时缓存也是按照这些思路实现的。

没有。 Class 为对象提供蓝图,当使用 new 运算符时,它会调用构造函数来初始化新对象。 Source.

如果您出于任何原因希望重用对象,您可能需要考虑将 Flyweight pattern as well as the Factory pattern 实施到您的项目中以获得最佳结果。

不,这不可能。创建静态方法以根据所需逻辑创建对象,并且不要忘记将构造函数设为私有。