0

Java is pass-by-value. This means that a called method acts on a copy of an object that was passed in, not on the original object.

If the object is not changed in the method, creating an actual copy seems unnecessary. So a compiler that implements the program to create such a copy would be pretty inefficient. Are all Java compilers (javac, gcj, ECJ, etc.) really doing that?

At least in the case where a parameter is declared final it would make a lot of sense not to copy.

EDIT

OK, so objects are not copied. I got confused because String is special in that it is copied (immutable). Sorry about my unknowings. Just to make up for it, here is a thousandth example of what happens when an object is passed:

import java.lang.System;

class C { int member; }

public class Test {
    static void subMethod(C object) { object.member=1; }

    public static void main(String[] args) {
        C object = new C();
        object.member=0;
        subMethod(object);
        System.out.println(object.member);  // prints "1"
    }
}
Jonathan
  • 358
  • 3
  • 14
  • Where did you read that Java is pass-by-value only? AFAIK that only applies to the primitive types. – Hubert Grzeskowiak Jan 11 '16 at 14:54
  • For non-primitive types, Java copies the reference of the object; it doesn't actually copy the complete object. For primitive-types, Java copies the value. – W.K.S Jan 11 '16 at 14:54
  • The reference to the same object is copied. Not the object. Both references are pointing to the same object then. – Fabian Barney Jan 11 '16 at 14:55
  • java copy the value of the reference (for visualization reason think of that as the memomory location) and does not create copies of objects. – SomeJavaGuy Jan 11 '16 at 14:55
  • 8
    @HubertGrzeskowiak Java is **always** pass by value. It passes **references** by value in the case of non-primitive types. – Boris the Spider Jan 11 '16 at 14:55
  • 1
    If we're not talking primitive data types, ie objects, JAVA is pass by reference. I have no idea where you got the idea that JAVA is pass by value... – TT. Jan 11 '16 at 14:55
  • 5
    @TT. if Java would be pass by reference at any point then you could do `a = new A()` where `a` is a parameter of the class `A` and this new reference would also change in the original variable that was passed to the method, hence it´s only pass-by-value... – SomeJavaGuy Jan 11 '16 at 14:57
  • Where is the difference between passing references as values vs passing references? Passing an object handle is almost the same as a reference in C. Change something through the reference and the original object changes. Pass-by-value is more like fire and forget: you can pass the variable to a function and be sure it doesn't get changed at all. – Hubert Grzeskowiak Jan 11 '16 at 15:07
  • @HubertGrzeskowiak see my comment on [an answer](https://stackoverflow.com/questions/34724379/does-java-really-always-copy-all-objects-passed-to-a-method/34724445?noredirect=1#comment57195042_34724445) for an example - there are plenty of other relevant comments there. – Boris the Spider Jan 11 '16 at 15:13
  • 1
    @Kevin Goodness, what nitpicking. JAVA passes references to objects around ... by value. Of course it doesn't pass references around by reference, that isn't done in any language. There's also no reference type as there is in C++. And really that just isn't the point of the OP. He thinks that objects are passed around by value which isn't the case (otherwise the object would be copied as it is in C++). Objects are passed around by reference. Putting it any different is just a recipe for confusion. Just me 2c. – TT. Jan 11 '16 at 15:23
  • @BoristheSpider I'm missing one thing in your answer. You're basically swapping the references, but not the values behind them, which I consider the attributes of the objects to be. – Hubert Grzeskowiak Jan 11 '16 at 15:26
  • I think we should overthink the way we define pass-by-reference and pass-by-value. We're not in C/C++ here where you can pass pointers around. Object references in Java are what pointers in C are and the attributes of an object are equivalent of C's values. So accessing the value of a pointer 'a' in C is like accessing an attribute of object 'a' in Java. – Hubert Grzeskowiak Jan 11 '16 at 15:29
  • @HubertGrzeskowiak the distinction is an important one. For exactly the reason you outlined - if references were not passed by-value then you would be able to change properties of the _reference_ and affect other users of _that reference_. As they are passed by-value, they are copied; so reassignment does not affect other users of the same reference. P.S. I think your comment has a "not" missing in the first sentence. – Boris the Spider Jan 11 '16 at 16:50

2 Answers2

3

Yes, Java is always pass-by-value. But for objects, it passes the reference value. In other words, the object isn't copied, but its reference is. Changing an object's attributes inside a method changes it outside the method as well.

From here,

However, Objects are not passed by reference. A correct statement would be Object references are passed by value.

On-topic: the compiler simply copies the reference to its chunk of memory in the stack.

BlueMoon93
  • 2,910
  • 22
  • 39
  • In my code the outer object is not changed: static void subMethod(String str) {str="change made from subMethod";} public static void main(String[] args) { String str = new String("original string"); subMethod(str); System.out.println(str); } – Jonathan Jan 11 '16 at 15:13
  • 1) Strings are special. http://stackoverflow.com/questions/14473488/is-string-a-primitive-or-an-object-in-android-or-java 2) You're assigning the reference to a new object. Since Java is pass-by-value, that doesn't affect the original object. If you did something like `obj.attribute++;` then it would affect the original object – BlueMoon93 Jan 11 '16 at 15:17
  • @JonathanEnders Strings are immutable, especially see [this answer](http://stackoverflow.com/a/707416/1799530) – SomeJavaGuy Jan 11 '16 at 15:18
  • All immutable objects (Integer, Double, String and so on.) can be treated as pass-by-value regardless the definition. You pass the object and you can be sure it doesn't get changed anywhere. – Hubert Grzeskowiak Jan 11 '16 at 15:31
1

Objects in Java are references, and it is this reference which is passed by value; meaning Java is pass-by-reference with objects for practical purposes.

EDIT

It seems my use of the term 'practical purposes' is causing a lot of controversy, so let me clarify. I simply meant that what most people think of when they think of 'pass-by-reference' is that changes to the passed in value are persisted outside of that method, which is the case in Java. e.g.

void someMethod(SomeClass a) {
    a.mutateState();
}
SomeClass a = new SomeClass();
someMethod(a); //passes reference to a by value; 
a.methodInvolvingSomeState(); //mutations of object state persist to here, as if the previous call were pass-by-reference.

That's all I meant by 'for practical purposes'; OP was under the impression that a copy of a was made, which I was trying to explain was not true. I am fully aware that java is always pass-by-value, hence explicitly stating that it is the reference that is passed by value. As has been pointed out in the comments there are plenty of occasions where it is not the same as if it were actually pass-by-reference, and it was not my intention to indicate that any of those were possible in Java.

jonk
  • 1,494
  • 11
  • 13
  • 7
    "_meaning Java is pass-by-reference_" **No!!** Java is **always** pass by value - in the case of objects it passes references by value. – Boris the Spider Jan 11 '16 at 14:56
  • 3
    @BorisTheSpider re-read my answer; I specifically said that it is the reference which is passed by value and that it was pass-by-reference for **practical purposes**. I am more than aware that java is always pass-by-value :) – jonk Jan 11 '16 at 14:57
  • Yes, you said that correctly. They you made the incorrect statement that "_Java is pass-by-reference_". It is not; it always passes by value. It passes references **by-value**. If Java passed by reference then one could reassign references and affect the usage of that reference throughout the code. So for "_practical_" (and by other) purposes, Java is pass by value. – Boris the Spider Jan 11 '16 at 14:59
  • When an object is passed to a method, a copy of the reference is actually passed, which means that the method can never invalidate the object passed to it (this is pass by value) – dsp_user Jan 11 '16 at 14:59
  • objects in Java are objects and not references – Sleiman Jneidi Jan 11 '16 at 15:00
  • @BoristheSpider I literally said exactly what you're saying... 'Objects in Java are references, **and it is this reference which is passed by value**' – jonk Jan 11 '16 at 15:01
  • @jonk agreed, your first sentence (clause) is correct. Your second sentence (sub-clause) however, is not. There is no way that "_meaning Java is pass-by-reference with objects_" is correct. Ever. – Boris the Spider Jan 11 '16 at 15:02
  • 1
    @jonk "practical purposes" Not really. Setting the reference inside the method to another object does not change the passed reference. But that wopuld be the case when Java would have been call-by-reference which it is not. – Fabian Barney Jan 11 '16 at 15:03
  • 1
    "pass-by-reference for practical purposes" a practical use of pass-by-reference (e.g. in C++) is to write a `swap` method. You can't do this in Java, because it is *actually* pass-by-value, so it is misleading to consider it "practically" pass-by-reference. – Andy Turner Jan 11 '16 at 15:03
  • @BoristheSpider by 'practical purposes' I meant that when you pass an object and make changes to it, those changes are persisted outside that method, as if it were passed by reference. I'll update my answer to make that clearer. – jonk Jan 11 '16 at 15:05
  • @jonk see above comments by myself and others. This is not the case, pass by reference would mean that, for example, ` void swap(T a, T b){ T tmp = a; a = b; b = tmp}` would be possible; which it is not. Pass by reference does not mean what you think it means - a reference has a specific meaning and this is not it. – Boris the Spider Jan 11 '16 at 15:06
  • 2
    @BoristheSpider I think jonk is more referring to mutating `a` or `b` in the method, e.g. calling `a.mutateState();`. However, I just think that trying to call this "practically pass-by-reference" is just making a simple rule harder. – Andy Turner Jan 11 '16 at 15:13
  • 1
    @AndyTurner agree - the argument is mostly a semantic one; but I think it's an important one and one that many people get wrong - leading to all sorts of confusion of the internet... – Boris the Spider Jan 11 '16 at 15:14
  • 1
    I have updated my answer with what I meant, I hope that I've cleared it up. I am aware of everything that has been said here, and wasn't trying to say any of it was possible in Java. It certainly looks like 'for practical purposes' was a poor choice of phrasing... – jonk Jan 11 '16 at 15:27
  • also @AndyTurner that was what I meant (all that I meant!). Used your example in my edit. – jonk Jan 11 '16 at 15:29