简体   繁体   中英

Java: getter method vs. public instance variable: performance and memory

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 (eg 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?

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.

Passing by reference vs. value is hard

In Java everything is passed by value. Primitive types are passed by their value, Complex types are passed by the value of their reference. Arrays are not primitive so their reference is passed around.

I could just make the arrays public ... Or, I could do getters

If they are public then other classes can change the array reference that your object contains itself. If there are getters that return reference to the array then callers can change the contents of the array. Both are pretty bad. This answers your addendum question as well.

I think the options are as follows:

  • Use getters for individual cells as @Bohemian suggests. If there is any locking of the array object is required there may be additional panalties here

  • Return reference to the array and trust your callers to not mess it up. Additional chekcs can be implemented by checking access at compile time

  • Maintain two copies of the array inside the object. One to return in the getter and the other for the real work. You can document that changing the array has no effect and assert that their contents are same when returning from getter.

Everything is pass by value , but the getter would be returning a reference to the array, no copies involved.

anyone who modifies would be seen by everyone with a reference to that array.

as for 1) performance, the only way to know is to benchmark. a get method is going to add overhead, but if your structures are huge, any accesses to elements in the structure is going to dwarf any overhead of an added method call.

as for 2) poor coding practice, it really depends on what you are doing. does your code need to ensure it can't be modified by anyone else? then return a copy. or better yet, force the caller to ask for a range of the data, and only return them a copy of the range they need.

Java passes everything by value. Java references are pointers passed by value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM