4

In the program

public static void main(String[] args){
    int x = 1;
    int y = 2;
    int[] z = new int[]{x, y};
    z[0] = 3;
    System.out.println(x); //prints 1
}

I expected that 3 would be printed. But 1 was. Why? I thought Java makes copy only of references, i.e. when we pass a refrence to a method, the method will operate with another reference to the same object. It's like C++ pointers and primitive types.

So I tried to consult JLS 10.6 and didn't find anything useful about it. Maybe I've got some misunderstanding about primitive types in Java. Could you clarify?

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Alupkers
  • 223
  • 1
  • 9
  • Its correct `x` contains only the value `1` so it ll prints. – SatyaTNV Jan 21 '16 at 07:12
  • No it´s not like c++ pointers, java is only `pass-by-value`. – SomeJavaGuy Jan 21 '16 at 07:15
  • @KevinEsche References aren't like C++ pointers... Hm, couldn't you explain the difference then? – Alupkers Jan 21 '16 at 07:16
  • @Alupkers you pass the reference by value. For primitiv types you only pass the value (there is no reference here). for example, if you pass an object to a method you are working on the same instance of the object, since the value of the reference is the same for the caller and the invoking method. So invoking methods on this object inside the method does also reflect in changes for the object in the calling method. But if you reassign the paramater in the method the changes wont reflect since you didn´t work on the reference itself, but only on the value of the reference. – SomeJavaGuy Jan 21 '16 at 07:19
  • 2
    @KevinEsche: Java references are a *lot* like C++ pointers, except we're not allowed to play with their values. What they aren't like is C++ *references*, since (as you say) Java doesn't have pass-by-reference. – T.J. Crowder Jan 21 '16 at 07:41

4 Answers4

11

Why does creating an array from primitives copy them?

For exactly the same reason that:

int a = 5;
int b = a;

...copies the value of a into b, without creating any kind of link between a and b: The value is copied, not some kind of reference to the variable.


Re your comment:

But when we operate on reference types, the reference copies, doesn't it?

Yes, it does, exactly like the number gets copied in your int scenario.

b = a (or your array initializer) works exactly the same way regardless of whether a and b are primitive type variables or reference type variables: The value in a is copied to b, and then there is no ongoing link between a and b.

The only difference is that when you're dealing with reference types, the value in the variable isn't the actual thing, it's a reference to the actual thing. So copying that reference from one variable into another just makes makes those two variables refer to the same thing, just like my code above makes a and b both have the value 5.

Consider: Let's create a list:

List<String> a = new ArrayList<String>();

That gives us something like this in memory:

              +----------+
a(55465)----->| the list |
              +----------+

The variable a contains a value which is a reference to an object. I've depicted that value above as 55465, but we never actually see the raw value in our Java code (and it changes as garbage collection is done). It's just a value, like any other value, which tells the JVM where to find the object in memory. You can think of it like a long containing a memory address (that's not what it really is, but it works conceptually).

Now we do this:

List<String> b = a;

Now we have something like this in memory:


a(55465)--+
          |    +----------+
          +--->| the list |
          |    +----------+
b(55465)--+

Both a and b contain a value which refers to the list.

You can see how that's exactly like:

int a = 5

gives us

a(5)

and then

int b = a;

gives us

a(5)
b(5)

Values are copied between variables, passed into functions, etc. The only difference with reference types is what that value is used for, how it's interpreted.

If so, I would say that java is pass by value in the sense of copying values of primitives and the references of reference types. Right?

No. "Pass by value" and "pass by reference" have a specific meaning in computing: It's about having a reference to a variable, not an object. This is what pass-by-reference looks like:

// NOT JAVA; Java doesn't have this
void foo(int &a) { // Fake pass-by-reference thing
    a = 3;
}

int a = 5;
foo(&a); // Fake pass-by-reference operator
System.out.println(a); // 3

Pass-by-reference has nothing to do with object references. The only thing they have in common is the word "reference." Java is a purely pass-by-value language.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • But when we operate on reference types, the reference copies, doesn't it? If so, I would say that java is pass by value in the sense of copying values of primitives and the references of reference types. Right? – Alupkers Jan 21 '16 at 07:15
  • 7
    @Alupkers: It's copying the value of the variable in every case - it's just that with reference types, the value of the variable *is* a reference, not an object. See also: http://stackoverflow.com/questions/32010172/what-is-the-difference-between-a-variable-object-and-reference/32010236#32010236 – Jon Skeet Jan 21 '16 at 07:19
  • @Alupkers: I've updated the answer to answer your comment. – T.J. Crowder Jan 21 '16 at 07:31
  • 3
    @T.J.Crowder+1 Nice explained for java is pass by value !! – bNd Jan 21 '16 at 07:35
0

Java is pass by value not reference. if you assign to array zero so it does not assigned to x.

bNd
  • 7,512
  • 7
  • 39
  • 72
-1

You did mistake here :

int x = 1;
int y = 2;
int[] z = new int[]{x, y};
z[0] = 3;
System.out.println(x); //prints 1 // You are printing x (where x = 1)

Here you print x so x = 1

If you print z[0] instead of x then it will print 3

Shiladittya Chakraborty
  • 4,270
  • 8
  • 45
  • 94
-1

z[0] = 3 assigns the value to array not to int x.

Adam Michalik
  • 9,678
  • 13
  • 71
  • 102
Priyesh Mishra
  • 119
  • 2
  • 8