6

Sorry for the noob questions. Passing by reference vs. value is hard!

So I have a class with pretty big data structures-- multidimensional arrays. I need to access these arrays from another class. I could just make the arrays public and do the classic objectWithStructures.structureOne. Or, I could do getters: adding a method like public int[][][] getStructureOne().

Does having a getter make a copy of the multidimensional array? Or does it pass it by reference and you just can't alter the object referenced?

I'm worried about memory and performance. But making the data structures public, while faster if it doesn't cause copies to be made, seems like poor coding practice.

ADDENDUM: So when I return a reference to an object (e.g. an array) using a getter method, can that object be edited by whoever uses the getter method? Or is it somehow "locked" for editing so that only the class it's in can alter that object?

4

4 回答 4

4

通过引用与值传递很难

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

我可以将数组公开......或者,我可以做吸气剂

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

我认为选项如下:

  • 正如@Bohemian 建议的那样,对单个单元格使用吸气剂。如果需要对数组对象进行任何锁定,则此处可能会有额外的问题

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

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

于 2012-09-18T01:11:32.307 回答
4

Actually in java, technically everything is pass by value, because a reference is the value of the memory address, however you can think of it as pass by reference.

As for performance, I doubt there's a measurable difference, because the JVM JIT compiler will probably in-line the accessor method (the "getter"). As a matter of style, it is considered better to use getters in preference to making your fields public.

As for safe publishing (allowing safe access to private data) - no, the object isn't "locked in read only mode"; it's completely editable because arrays are mutable.

To safely allow access to your data array, you basically have two choices:

  1. return a copy of the array from your getter - expensive
  2. provide an API that returns the element at a given position - simple to code, but may be harder to change array dimensions later because the API has been defined for your class

An example of providing an API might be:

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

This method is completely safe, because primitives (like int) are passed by value - it the caller changes the value of the variable into which the result of this method is assigned, nothing happens to the array.

于 2012-09-18T00:51:34.217 回答
1

一切都是按传递的,但 getter 将返回对数组的引用,不涉及副本。

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

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

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

于 2012-09-18T00:26:51.440 回答
0

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

于 2012-09-18T03:54:02.883 回答