代码之家  ›  专栏  ›  技术社区  ›  Yksisarvinen

为什么Java不提供默认复制构造函数?

  •  -4
  • Yksisarvinen  · 技术社区  · 6 年前

    注:我知道这个问题: 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 回复  |  直到 6 年前
        1
  •  3
  •   Andy Turner    6 年前

    有什么阻止Java创建隐式复制构造函数,它将调用所有成员上的复制构造函数吗?

    主要的事实是,这显然不是它应该做的。

    在这种情况下,您可能需要一个深度复制;在这种情况下,您可能需要一个浅层复制;在另一种情况下,您可能根本不希望复制实例;可能您希望以这些方式的混合方式复制某个特定类的字段。

    另外,添加这个构造函数是另一种方法:在方法数量很重要的环境中(例如,Android的64K DEX限制),你要为你不想要的东西买单。

    如果你需要的话,最好允许你做,让它明确。


    但是什么 停止 Java有这个吗?

    假设您可以手动定义一个复制构造函数,那么让它们自动添加在技术上显然是可行的。

    我建议您不能这样做的一个原因是,对于您不希望被复制的类,没有“删除”构造函数的语言机制。

    很容易指出您不需要默认的ctor:只需定义您自己的ctor,并使用任何签名。但是对于默认的copy-ctor不能这样做:根据定义,copy-ctor将只具有签名 YourClass(YourClass instance) ;因此,您不能要求(例如)定义一个抛出的显式复制ctor,因为您已经将编译时错误(不存在此类ctor)更改为运行时错误(它存在,但抛出)。

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

    从绝对意义上讲,这不是不可能的,但是要改变语言以添加一个可以在现有语言中实现的特性需要做大量的工作。

        2
  •  3
  •   Soutzikevich    6 年前

    但确实如此。这是一个方法 clone() 并在类中实现 Object .

    因此,你想要做的,可以通过以下方式实现:

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