Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 可变对象的getter中的深度复制_Java_Oop - Fatal编程技术网

Java 可变对象的getter中的深度复制

Java 可变对象的getter中的深度复制,java,oop,Java,Oop,总是返回集合/对象字段的副本会有开销吗?当然会有开销,但是已经有一些框架类这样做了。《有效的Java》一书中也对其进行了描述 记住: “类应该是不可变的,除非有很好的理由使它们变为可变的……如果一个类不能变为不可变的,请尽可能限制它的可变性。” 当您想要创建不可变类时,可以使用如下框架: 例如,请清楚地检查此项,是的,这将是一项开销。。。与返回引用或浅层副本相比 但这不是重点。真正的问题是开销是否合理/必要,以及是否可以通过使用其他数据结构/设计/技术来避免。这些问题的答案取决于上下文 以下是

总是返回集合/对象字段的副本会有开销吗?

当然会有开销,但是已经有一些框架类这样做了。《有效的Java》一书中也对其进行了描述

记住:

“类应该是不可变的,除非有很好的理由使它们变为可变的……如果一个类不能变为不可变的,请尽可能限制它的可变性。”

当您想要创建不可变类时,可以使用如下框架:


例如,请清楚地检查此项,是的,这将是一项开销。。。与返回引用或浅层副本相比

但这不是重点。真正的问题是开销是否合理/必要,以及是否可以通过使用其他数据结构/设计/技术来避免。这些问题的答案取决于上下文


以下是一些插图:

  • 如果目标对象getter返回不可变对象,则不需要复制。例如,返回
    字符串的任何getter
  • 如果目标对象getter返回的对象不是目标对象抽象的一部分,则不需要复制。示例
    list.get(int)
    Iterator.next()
  • 如果目标对象getter返回一个可变对象(或数组)并且返回的对象是对象内部状态的一部分并且目标不一定信任调用方,那么getter应该复制或包装它。。。或者可能存在安全问题
  • 这同样适用于与安全无关的情况;e、 g.
    ArrayList.toArray(…)
    将列表复制到单独的数组中,而不是返回列表的备份数组。(类似于
    getChars()
    对于
    String
    StringBuffer
    ,等等)这都是关于维护抽象边界的,这样on类就不会“破坏”另一个抽象边界
  • 如果目标对象getter返回一个可变对象(或数组)并且返回的对象是对象内部状态的一部分,但是目标对象的API/抽象边界被设计为“多孔”(例如,出于性能原因),那么复制可能会弄巧成拙
    其中,只有3例是严格强制克隆的。在2、4和5中,您可能会认为这是一个如何为类、库和应用程序设计公共(或内部)API的问题。通常有很多可行的选择。

    对不起,但是“是否会超出预算”显然是“给我你的意见”的大概意思。从这个意义上说,你的问题不适合这里。我的意见是:这要看情况而定。如果您的设计效果更好,如果您返回副本,那么就这样做。如果各方都在处理相同的对象这一点很重要,那么也许你不需要创建克隆。半相关:@StephenC如果你能给出一些在可变对象的getter中需要克隆对象的例子,那就太好了