Java:getter方法与公共实例变量:性能和内存

时间:2012-09-18 00:21:24

标签: java performance memory-management

对于noob问题抱歉。通过引用与价值相结合是很难的!

所以我有一个具有相当大的数据结构的类 - 多维数组。我需要从另一个类访问这些数组。我可以将数组公开并执行经典的objectWithStructures.structureOne。或者,我可以做getters:添加像public int [] [] [] getStructureOne()这样的方法。

让getter制作多维数组的副本吗?或者它通过引用传递它,你只是不能改变引用的对象?

我担心记忆和表现。但是如果数据结构不公开,那么将数据结构公之于众,如果它不会导致副本更快,则看起来就像编码不好。

ADDENDUM:所以当我使用getter方法返回对象(例如数组)的引用时,是否可以使用getter方法编辑该对象?或者它是否以某种方式“锁定”进行编辑,以便只有它所在的类可以改变该对象?

4 个答案:

答案 0 :(得分:4)

实际上在java中,从技术上讲,所有内容都是按值传递的,因为引用是内存地址的,但您可以将其视为通过引用传递。

至于性能,我怀疑是否存在可衡量的差异,因为JVM JIT编译器可能会在访问器方法(“getter”)内嵌。作为一种风格问题,最好使用吸气剂,而不是将你的田地公之于众。

至于安全发布(允许安全访问私人数据) - 否,该对象不是“锁定在只读模式”;它是完全可编辑的,因为数组是可变的。

为了安全地允许访问您的数据阵列,您基本上有两个选择:

  1. 从您的getter中返回数组的副本 - 昂贵的
  2. 提供一个返回给定位置元素的API - 对代码很简单,但稍后可能更难更改数组维度,因为已经为您的类定义了API
  3. 提供API的示例可能是:

    public int getStructureOne(int x, int y, int z) {
        return structureOne[x][y][z];
    }
    

    这个方法是完全安全的,因为原语(如int)是按值传递的 - 调用者改变了赋值方法的变量值,数组没有任何反应。< / p>

答案 1 :(得分:4)

  

通过引用传递与价值很难

在Java中,一切都按值传递。原始类型通过其值传递,复杂类型通过其引用的值传递。数组不是原始的,因此它们的引用会被传递。

  

我可以将数组公开......或者,我可以做getters

如果它们是public,则其他类可以更改对象包含的数组引用。如果有getter返回对数组的引用,则调用者可以更改数组的内容。两者都很糟糕。这也回答了你的补遗问题。

我认为选项如下:

  • @Bohemian建议,对单个细胞使用吸气剂。如果需要锁定数组对象,可能会有额外的panalties

  • 返回对数组的引用,并相信您的调用者不会搞砸它。可以通过在编译时检查访问来实现额外的chekcs

  • 在对象内维护两个副本。一个是在吸气剂中返回,另一个是为了真正的工作。您可以记录更改数组无效并断言从getter返回时其内容相同。

答案 2 :(得分:1)

所有内容都通过 value 传递,但是getter会将引用返回给数组,不涉及任何副本。

每个修改过的人都会被所有人看到并引用该数组。

至于1)表现,唯一知道的方法就是基准。 get方法会增加开销,但是如果你的结构很大,那么对结构中元素的任何访问都会使添加的方法调用的任何开销相形见绌。

2)编码实践不佳,这实际上取决于你在做什么。您的代码是否需要确保其他人无法修改?然后返回一份副本。或者更好的是,强制呼叫者询问一系列数据,并只返回他们所需范围的副本。

答案 3 :(得分:0)

Java按值传递所有内容。 Java引用是按值传递的指针。