为什么Java不提供默认的副本构造函数?

时间:2019-01-19 14:03:50

标签: java language-lawyer

注意:我知道这个问题:Why doesn't Java have a copy constructor?。这个问题稍有不同。

我知道以下代码片段仅创建对某处存在的对象的新引用:

MyClass obj = new MyClass();
MyClass copy = obj;

但是在以下情况下,为什么Java不提供默认的复制构造函数:

MyClass obj = new MyClass();
MyClass copy = new MyClass(obj);

我相信隐式复制构造函数可以做一些类似于C ++的事情,即在每个成员上调用复制构造函数。假定所有管理资源的类都正确实现了其复制构造函数,这将导致该对象的深层复制。

添加此类功能也应向后兼容,因为如果没有该类的显式复制构造函数,则第二个代码段将无法编译。

因此,为了使我的问题更准确:

  • 有什么阻止Java创建隐式副本构造函数的方法,该方法会在所有成员上调用副本构造函数?
  • 现在是否可以添加隐式副本构造函数来破坏任何现有程序?

2 个答案:

答案 0 :(得分:3)

  

有什么阻止Java创建隐式副本构造函数的方法,该构造函数将在所有成员上调用副本构造函数?

主要是事实,这显然不是应该执行的操作。

在这种情况下,也许您想要一个深层副本;在这种情况下,也许您想要一个浅表副本;也许您根本不希望在其他情况下复制实例;也许您希望通过这些方式的混合来复制特定类的字段。

此外,添加此构造函数是另一种方法:在方法数量很重要的环境(例如Android的64k Dex限制)中,您要为不需要的东西付费。

通过明确显示,更好地允许您执行此操作。


但是阻止 Java的原因是什么?

鉴于您可以手动定义副本构造函数,因此在技术上显然可以自动添加它们。

我建议您不能这样做的原因是,没有语言机制可以“删除”您不想复制的类的构造函数。

很容易表明您不需要默认的ctor:只需定义自己的带任何签名的ctor。但是您不能使用默认的复制ctor来做同样的事情:根据定义,复制ctor只会具有签名YourClass(YourClass instance);因此,您不必要求定义一个抛出的显式副本ctor,因为这样您就可以将编译时错误(不存在此类ctor)更改为运行时错误(存在但已抛出)。

因此,您必须开始发明额外的机制来删除构造函数-例如特殊注释。但这需要更改工具以支持它。

从绝对意义上讲这并非不可能-但这需要大量工作来更改语言以添加可以在现有语言中实现的功能。

答案 1 :(得分:2)

但是确实如此。该方法称为clone(),并在类Object中实现。

因此,您可以通过以下操作来实现:

MyClass obj = new MyClass(); 
MyClass copy = (MyClass) obj.clone();