1

Possible Duplicate:
Is Java pass by reference?

I have a question about passing by value and passing by reference in java.

I have a "Graph" class that I wrote to display a long array of doubles as a graph, The (simplified) constructor looks like this.

private double[] Values;

public Graph(double[] values) {
   Values = values;
}

The array can be quite long and take up a reasonable amount of memory.

Essentially my question is this: If I call the constructor to create a new graph, will the array "Values" be a copy of the array that's passed to it, or will it be a reference?

In my mind, Primitives are "pass by value" and Objects are "pass by reference", which should mean that the array would be a copy. Although I'm aware that this definition is not technically correct.

If I am correct, and the array is a copy, what would be the best way to reduce the amount of memory this class uses, and reference the array from another class? Would an abstract GetValues() method be a good way of achieving this?

Thanks in advance,

Chris.

Community
  • 1
  • 1
Chris192
  • 43
  • 5
  • 2
    Java = pass by value. http://stackoverflow.com/questions/40480/is-java-pass-by-reference – Alfabravo Feb 22 '12 at 16:34
  • 7
    Java "passes references by value". – Tom Hawtin - tackline Feb 22 '12 at 16:37
  • 1
    If you want to think about java passing in low level c terms, the best fit is `const Object*` - a pointer to a constant object. Best to leave references out of it - that's just confusing because that's already defined in c++ terms and is quite different to what java does. – Voo Feb 22 '12 at 16:46
  • Thanks for clearing that up. I was aware that it wasn't a correct definition, but now I know the correct way. Thanks – Chris192 Feb 22 '12 at 16:58

6 Answers6

7

While double is a primitive type, double[] is an Object type (array), so, no, the entire array will not be passed to the constructor, instead the array will be passed as "value of a reference". You will not be able to replace the array inside the constructor, but you could, if you wanted, replace individual values in the array.

Aleks G
  • 56,435
  • 29
  • 168
  • 265
  • 1
    Just note that it's still not by reference. If you pass things by reference we can implement a swap method. Which just doesn't work in java at all.. – Voo Feb 22 '12 at 16:41
  • Yes, naturally, this is "reference by value" – Aleks G Feb 22 '12 at 16:45
  • 2
    Ok then you're using "reference" as a synonym for pointer. That's the problem that we're reusing terms with completely different definitions here, sigh. – Voo Feb 22 '12 at 16:51
  • @Voo the Java term is "reference", not "pointer". You can't do pointer arithmetic. It doesn't point to a spot in memory. The GC can move the object around in memory, without needing to update the reference. – ILMTitan Feb 22 '12 at 17:02
4

Java is pass-by-value, period.

See the JLS, 4.12.3 Kinds of Variables:

Method parameters (§8.4.1) name argument values passed to a method. For every parameter declared in a method declaration, a new parameter variable is created each time that method is invoked (§15.12). The new variable is initialized with the corresponding argument value from the method invocation. The method parameter effectively ceases to exist when the execution of the body of the method is complete.

EDIT: To clarify my answer: The types of Java are divided in two categories: The primitives and the reference types. Whenever you call a method (or a constructor), the parameters get copied (because Java is pass-by-value). The primitives get copied entirely and for reference types, the reference gets copied. Java will never automatically deep copy anything, so as arrays are reference types, only the reference to the array gets copied.

Johannes Weiss
  • 52,533
  • 16
  • 102
  • 136
  • You may say that the object's reference is passed by value. This has the effect that the object itself is passed by reference. – phlogratos Feb 22 '12 at 16:40
  • 3
    @phlogratos Is that so? Then please write a `swap(Object a, Object b)` method. That's basically the litmus test for pass-by-reference. – Voo Feb 22 '12 at 16:42
  • 1
    -1. You don't answer the essential question "If I call the constructor, will the array be a copy, or will it be a reference?", but imply the answer is "a copy", which is wrong (even if your answer is technically correct). It is copying the reference, not the array. – ILMTitan Feb 22 '12 at 16:53
  • @ILMTitan, as I see what you mean, I have edited my answer to clarify that point. – Johannes Weiss Feb 22 '12 at 17:15
  • @Voo: Here it is: void swap(final Object a, final Object b) { try { Object tmp = a.getClass().newInstance(); org.apache.commons.beanutils.PropertyUtils.copyProperties(tmp, a); org.apache.commons.beanutils.PropertyUtils.copyProperties(a, b); org.apache.commons.beanutils.PropertyUtils.copyProperties(b, tmp); } catch(Exception e) { throw new RuntimeException(e); } } – phlogratos Feb 22 '12 at 17:25
  • 1
    This will only work for simple Java Beans and has nothing to do with call-by-reference. It will especially not work for immutable types as `Integer`, `String`, `Boolean`, ... and complex types as `List`s, ... – Johannes Weiss Feb 22 '12 at 17:30
  • 1
    @phlogratos Umn.. you should really look up what `copyProperties` does if you think that's a swap method. Or even simpler - just for a second think about all those classes that don't have an empty constructor. – Voo Feb 22 '12 at 23:50
2

It will be a reference of values. Java is Pass-by-value, but what's passed by value is a reference to the array, as the array is an object.

See also this answer, from just a few days ago.

Community
  • 1
  • 1
MByD
  • 135,866
  • 28
  • 264
  • 277
0

It will be a reference. the parameter values is passed "reference by value", and the reference is attached to Values.

Thus - any cahnge to Graph.Value will also be reflected to values and vise versa.

amit
  • 175,853
  • 27
  • 231
  • 333
0

Array is a reference type, passing by copy applies only to primitive types, which an array isn't. The other reference types include classes and interfaces, by the way.

Malcolm
  • 41,014
  • 11
  • 68
  • 91
0
// Points:
// 1) primitive variables store values
// 2) object variables store addresses(location in the heap)
// 3) array being an object itself, the variables store addresses again (location in the heap)

// With primitives, the bit by bit copy of the parameters, results in the
// value being copied. Hence any changes to the variable does not propagate
// outside
void changePrimitive(int a) {
    a = 5;
}

// With objects, the bit by bit copy of the parameters, results in the address
// begin copied. Hence any changes using that variable affects the same object
// and is propogated outside.
class obj {
    int val;
}
void changeObject(obj a) {
    a.val = 10;
}

// Array is itself an object which can hold primitives or objects internally.
// A bit by bit copy of the parameters, results in the array's address
// being copied. Hence any changes to the array contents reflects in all 
// the locations having that array. 
void changeArray(int arr[]) {
    arr[0] = 9;
    arr[1] = 8;
}

// NOTE: when object/array variable is assigned a new value, the original
// object/array is never affected. The variable would just point to the
// new object/array memory location.
void assignObj(obj a) {
    a = new obj();
    a.val = 10;
}