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



很抱歉收到noob问题。通过引用和价值传递是很难的!

所以我有一个类,它有相当大的数据结构——多维数组。我需要从另一个类访问这些数组。我可以将数组公开,然后使用经典的objectWithStructures.structureOne。或者,我可以使用getters:添加一个方法,比如public int[][][]getStructureOne()。

拥有getter是否会复制多维数组?或者它是通过引用传递的,而你却无法更改引用的对象?

我担心记忆力和表现。但是,将数据结构公开,如果不导致复制,则会更快,这似乎是一种糟糕的编码实践。

附录:所以,当我使用getter方法返回对对象(例如数组)的引用时,使用getter的人可以编辑该对象吗?或者它是以某种方式"锁定"进行编辑,这样只有它所在的类才能更改该对象?

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

至于性能,我怀疑是否存在可测量的差异,因为JVM JIT编译器可能会内联访问器方法("getter")。就风格而言,人们认为使用getter比公开字段更好。

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

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

  1. 从getter返回数组的副本-代价高昂
  2. 提供一个在给定位置返回元素的API-代码简单,但以后可能更难更改数组维度,因为API是为类定义的

提供API的示例可能是:

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

此方法是完全安全的,因为基元(如int)是通过值传递的——如果调用方更改将此方法的结果分配到的变量的值,则数组不会发生任何变化。

按引用与值传递是很难的

在Java中,所有内容都是通过值传递的。基元类型通过其值传递,复杂类型通过其引用的值传递。数组不是基元,因此它们的引用是传递的。

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

如果它们是public,那么其他类可以更改对象本身包含的数组引用。如果有getter返回对数组的引用,那么调用者可以更改数组的内容。两者都很糟糕。这也回答了您的附录问题。

我认为选项如下:

  • 按照@Bohemian的建议,对单个细胞使用getter。如果需要对阵列对象进行任何锁定,则此处可能有额外的通用

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

  • 在对象内维护数组的两个副本。一个在getter中返回,另一个在实际工作中返回。您可以记录更改数组没有任何效果,并在从getter返回时断言它们的内容是相同的。

所有东西都通过传递,但getter将向数组返回引用,不涉及副本。

任何修改的人都会被每个引用该数组的人看到。

至于1)性能,唯一的方法就是进行基准测试。get方法会增加开销,但如果您的结构很大,那么对结构中元素的任何访问都会使添加的方法调用的任何开销相形见绌。

至于糟糕的编码实践,这实际上取决于你在做什么。您的代码是否需要确保不能被其他人修改?然后返回一份副本。或者更好的方法是,强制调用者请求一个数据范围,并且只向他们返回所需范围的副本。

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

最新更新