you - Is Java “pass-by-reference” or “pass-by-value”?




what is pass by value and pass by reference (20)

A reference is always a value when represented, no matter what language you use.

Getting an outside of the box view, let's look at Assembly or some low level memory management. At the CPU level a reference to anything immediately becomes a value if it gets written to memory or to one of the CPU registers. (That is why pointer is a good definition. It is a value, which has a purpose at the same time).

Data in memory has a Location and at that location there is a value (byte,word, whatever). In Assembly we have a convenient solution to give a Name to certain Location (aka variable), but when compiling the code, the assembler simply replaces Name with the designated location just like your browser replaces domain names with IP addresses.

Down to the core it is technically impossible to pass a reference to anything in any language without representing it (when it immediately becomes a value).

Lets say we have a variable Foo, its Location is at the 47th byte in memory and its Value is 5. We have another variable Ref2Foo which is at 223rd byte in memory, and its value will be 47. This Ref2Foo might be a technical variable, not explicitly created by the program. If you just look at 5 and 47 without any other information, you will see just two Values. If you use them as references then to reach to 5 we have to travel:

(Name)[Location] -> [Value at the Location]
---------------------
(Ref2Foo)[223]  -> 47
(Foo)[47]       -> 5

This is how jump-tables work.

If we want to call a method/function/procedure with Foo's value, there are a few possible way to pass the variable to the method, depending on the language and its several method invocation modes:

  1. 5 gets copied to one of the CPU registers (ie. EAX).
  2. 5 gets PUSHd to the stack.
  3. 47 gets copied to one of the CPU registers
  4. 47 PUSHd to the stack.
  5. 223 gets copied to one of the CPU registers.
  6. 223 gets PUSHd to the stack.

In every cases above a value - a copy of an existing value - has been created, it is now upto the receiving method to handle it. When you write "Foo" inside the method, it is either read out from EAX, or automatically dereferenced, or double dereferenced, the process depends on how the language works and/or what the type of Foo dictates. This is hidden from the developer until she circumvents the dereferencing process. So a reference is a value when represented, because a reference is a value that has to be processed (at language level).

Now we have passed Foo to the method:

  • in case 1. and 2. if you change Foo (Foo = 9) it only affects local scope as you have a copy of the Value. From inside the method we cannot even determine where in memory the original Foo was located.
  • in case 3. and 4. if you use default language constructs and change Foo (Foo = 11), it could change Foo globally (depends on the language, ie. Java or like Pascal's procedure findMin(x, y, z: integer;var m: integer);). However if the language allows you to circumvent the dereference process, you can change 47, say to 49. At that point Foo seems to have been changed if you read it, because you have changed the local pointer to it. And if you were to modify this Foo inside the method (Foo = 12) you will probably FUBAR the execution of the program (aka. segfault) because you will write to a different memory than expected, you can even modify an area that is destined to hold executable program and writing to it will modify running code (Foo is now not at 47). BUT Foo's value of 47 did not change globally, only the one inside the method, because 47 was also a copy to the method.
  • in case 5. and 6. if you modify 223 inside the method it creates the same mayhem as in 3. or 4. (a pointer, pointing to a now bad value, that is again used as a pointer) but this is still a local problem, as 223 was copied. However if you are able to dereference Ref2Foo (that is 223), reach to and modify the pointed value 47, say, to 49, it will affect Foo globally, because in this case the methods got a copy of 223 but the referenced 47 exists only once, and changing that to 49 will lead every Ref2Foo double-dereferencing to a wrong value.

Nitpicking on insignificant details, even languages that do pass-by-reference will pass values to functions, but those functions know that they have to use it for dereferencing purposes. This pass-the-reference-as-value is just hidden from the programmer because it is practically useless and the terminology is only pass-by-reference.

Strict pass-by-value is also useless, it would mean that a 100 Mbyte array should have to be copied every time we call a method with the array as argument, therefore Java cannot be stricly pass-by-value. Every language would pass a reference to this huge array (as a value) and either employs copy-on-write mechanism if that array can be changed locally inside the method or allows the method (as Java does) to modify the array globally (from the caller's view) and a few languages allows to modify the Value of the reference itself.

So in short and in Java's own terminology, Java is pass-by-value where value can be: either a real value or a value that is a representation of a reference.

https://code.i-harness.com

I always thought Java was pass-by-reference.

However, I've seen a couple of blog posts (for example, this blog) that claim that it isn't.

I don't think I understand the distinction they're making.

What is the explanation?


In Java only references are passed and are passed by value:

Java arguments are all passed by value (the reference is copied when used by the method) :

In the case of primitive types, Java behaviour is simple: The value is copied in another instance of the primitive type.

In case of Objects, this is the same: Object variables are pointers (buckets) holding only Object’s address that was created using the "new" keyword, and are copied like primitive types.

The behaviour can appear different from primitive types: Because the copied object-variable contains the same address (to the same Object) Object's content/members might still be modified within a method and later access outside, giving the illusion that the (containing) Object itself was passed by reference.

"String" Objects appear to be a perfect counter-example to the urban legend saying that "Objects are passed by reference":

In effect, within a method you will never be able, to update the value of a String passed as argument:

A String Object, holds characters by an array declared final that can't be modified. Only the address of the Object might be replaced by another using "new". Using "new" to update the variable, will not let the Object be accessed from outside, since the variable was initially passed by value and copied.


This will give you some insights of how Java really works to the point that in your next discussion about Java passing by reference or passing by value you'll just smile :-)

Step one please erase from your mind that word that starts with 'p' "_ _ _ _ _ _ _", especially if you come from other programming languages. Java and 'p' cannot be written in the same book, forum, or even txt.

Step two remember that when you pass an Object into a method you're passing the Object reference and not the Object itself.

  • Student: Master, does this mean that Java is pass-by-reference?
  • Master: Grasshopper, No.

Now think of what an Object's reference/variable does/is:

  1. A variable holds the bits that tell the JVM how to get to the referenced Object in memory (Heap).
  2. When passing arguments to a method you ARE NOT passing the reference variable, but a copy of the bits in the reference variable. Something like this: 3bad086a. 3bad086a represents a way to get to the passed object.
  3. So you're just passing 3bad086a that it's the value of the reference.
  4. You're passing the value of the reference and not the reference itself (and not the object).
  5. This value is actually COPIED and given to the method.

In the following (please don't try to compile/execute this...):

1. Person person;
2. person = new Person("Tom");
3. changeName(person);
4.
5. //I didn't use Person person below as an argument to be nice
6. static void changeName(Person anotherReferenceToTheSamePersonObject) {
7.     anotherReferenceToTheSamePersonObject.setName("Jerry");
8. }

What happens?

  • The variable person is created in line #1 and it's null at the beginning.
  • A new Person Object is created in line #2, stored in memory, and the variable person is given the reference to the Person object. That is, its address. Let's say 3bad086a.
  • The variable person holding the address of the Object is passed to the function in line #3.
  • In line #4 you can listen to the sound of silence
  • Check the comment on line #5
  • A method local variable -anotherReferenceToTheSamePersonObject- is created and then comes the magic in line #6:
    • The variable/reference person is copied bit-by-bit and passed to anotherReferenceToTheSamePersonObject inside the function.
    • No new instances of Person are created.
    • Both "person" and "anotherReferenceToTheSamePersonObject" hold the same value of 3bad086a.
    • Don't try this but person==anotherReferenceToTheSamePersonObject would be true.
    • Both variables have IDENTICAL COPIES of the reference and they both refer to the same Person Object, the SAME Object on the Heap and NOT A COPY.

A picture is worth a thousand words:

Note that the anotherReferenceToTheSamePersonObject arrows is directed towards the Object and not towards the variable person!

If you didn't get it then just trust me and remember that it's better to say that Java is pass by value. Well, pass by reference value. Oh well, even better is pass-by-copy-of-the-variable-value! ;)

Now feel free to hate me but note that given this there is no difference between passing primitive data types and Objects when talking about method arguments.

You always pass a copy of the bits of the value of the reference!

  • If it's a primitive data type these bits will contain the value of the primitive data type itself.
  • If it's an Object the bits will contain the value of the address that tells the JVM how to get to the Object.

Java is pass-by-value because inside a method you can modify the referenced Object as much as you want but no matter how hard you try you'll never be able to modify the passed variable that will keep referencing (not p _ _ _ _ _ _ _) the same Object no matter what!


The changeName function above will never be able to modify the actual content (the bit values) of the passed reference. In other word changeName cannot make Person person refer to another Object.


Of course you can cut it short and just say that Java is pass-by-value!


A few corrections to some posts.

C does NOT support pass by reference. It is ALWAYS pass by value. C++ does support pass by reference, but is not the default and is quite dangerous.

It doesn't matter what the value is in Java: primitive or address(roughly) of object, it is ALWAYS passed by value.

If a Java object "behaves" like it is being passed by reference, that is a property of mutability and has absolutely nothing to do with passing mechanisms.

I am not sure why this is so confusing, perhaps because so many Java "programmers" are not formally trained, and thus do not understand what is really going on in memory?


As many people mentioned it before, Java is always pass-by-value

Here is another example that will help you understand the difference (the classic swap example):

public class Test {
  public static void main(String[] args) {
    Integer a = new Integer(2);
    Integer b = new Integer(3);
    System.out.println("Before: a = " + a + ", b = " + b);
    swap(a,b);
    System.out.println("After: a = " + a + ", b = " + b);
  }

  public static swap(Integer iA, Integer iB) {
    Integer tmp = iA;
    iA = iB;
    iB = tmp;
  }
}

Prints:

Before: a = 2, b = 3
After: a = 2, b = 3

This happens because iA and iB are new local reference variables that have the same value of the passed references (they point to a and b respectively). So, trying to change the references of iA or iB will only change in the local scope and not outside of this method.


Basically, reassigning Object parameters doesn't affect the argument, e.g.,

private void foo(Object bar) {
    bar = null;
}

public static void main(String[] args) {
    String baz = "Hah!";
    foo(baz);
    System.out.println(baz);
}

will print out "Hah!" instead of null. The reason this works is because bar is a copy of the value of baz, which is just a reference to "Hah!". If it were the actual reference itself, then foo would have redefined baz to null.


I can't believe that nobody mentioned Barbara Liskov yet. When she designed CLU in 1974, she ran into this same terminology problem, and she invented the term call by sharing (also known as call by object-sharing and call by object) for this specific case of "call by value where the value is a reference".


I feel like arguing about "pass-by-reference vs pass-by-value" is not super-helpful.

If you say, "Java is pass-by-whatever (reference/value)", in either case, you're not provide a complete answer. Here's some additional information that will hopefully aid in understanding what's happening in memory.

Crash course on stack/heap before we get to the Java implementation: Values go on and off the stack in a nice orderly fashion, like a stack of plates at a cafeteria. Memory in the heap (also known as dynamic memory) is haphazard and disorganized. The JVM just finds space wherever it can, and frees it up as the variables that use it are no longer needed.

Okay. First off, local primitives go on the stack. So this code:

int x = 3;
float y = 101.1f;
boolean amIAwesome = true;

results in this:

When you declare and instantiate an object. The actual object goes on the heap. What goes on the stack? The address of the object on the heap. C++ programmers would call this a pointer, but some Java developers are against the word "pointer". Whatever. Just know that the address of the object goes on the stack.

Like so:

int problems = 99;
String name = "Jay-Z";

An array is an object, so it goes on the heap as well. And what about the objects in the array? They get their own heap space, and the address of each object goes inside the array.

JButton[] marxBros = new JButton[3];
marxBros[0] = new JButton("Groucho");
marxBros[1] = new JButton("Zeppo");
marxBros[2] = new JButton("Harpo");

So, what gets passed in when you call a method? If you pass in an object, what you're actually passing in is the address of the object. Some might say the "value" of the address, and some say it's just a reference to the object. This is the genesis of the holy war between "reference" and "value" proponents. What you call it isn't as important as that you understand that what's getting passed in is the address to the object.

private static void shout(String name){
    System.out.println("There goes " + name + "!");
}

public static void main(String[] args){
    String hisName = "John J. Jingleheimerschmitz";
    String myName = hisName;
    shout(myName);
}

One String gets created and space for it is allocated in the heap, and the address to the string is stored on the stack and given the identifier hisName, since the address of the second String is the same as the first, no new String is created and no new heap space is allocated, but a new identifier is created on the stack. Then we call shout(): a new stack frame is created and a new identifier, name is created and assigned the address of the already-existing String.

So, value, reference? You say "potato".


I just noticed you referenced my article.

The Java Spec says that everything in Java is pass-by-value. There is no such thing as "pass-by-reference" in Java.

The key to understanding this is that something like

Dog myDog;

is not a Dog; it's actually a pointer to a Dog.

What that means, is when you have

Dog myDog = new Dog("Rover");
foo(myDog);

you're essentially passing the address of the created Dog object to the foo method.

(I say essentially because Java pointers aren't direct addresses, but it's easiest to think of them that way)

Suppose the Dog object resides at memory address 42. This means we pass 42 to the method.

if the Method were defined as

public void foo(Dog someDog) {
    someDog.setName("Max");     // AAA
    someDog = new Dog("Fifi");  // BBB
    someDog.setName("Rowlf");   // CCC
}

let's look at what's happening.

  • the parameter someDog is set to the value 42
  • at line "AAA"
    • someDog is followed to the Dog it points to (the Dog object at address 42)
    • that Dog (the one at address 42) is asked to change his name to Max
  • at line "BBB"
    • a new Dog is created. Let's say he's at address 74
    • we assign the parameter someDog to 74
  • at line "CCC"
    • someDog is followed to the Dog it points to (the Dog object at address 74)
    • that Dog (the one at address 74) is asked to change his name to Rowlf
  • then, we return

Now let's think about what happens outside the method:

Did myDog change?

There's the key.

Keeping in mind that myDog is a pointer, and not an actual Dog, the answer is NO. myDog still has the value 42; it's still pointing to the original Dog (but note that because of line "AAA", its name is now "Max" - still the same Dog; myDog's value has not changed.)

It's perfectly valid to follow an address and change what's at the end of it; that does not change the variable, however.

Java works exactly like C. You can assign a pointer, pass the pointer to a method, follow the pointer in the method and change the data that was pointed to. However, you cannot change where that pointer points.

In C++, Ada, Pascal and other languages that support pass-by-reference, you can actually change the variable that was passed.

If Java had pass-by-reference semantics, the foo method we defined above would have changed where myDog was pointing when it assigned someDog on line BBB.

Think of reference parameters as being aliases for the variable passed in. When that alias is assigned, so is the variable that was passed in.


I thought I'd contribute this answer to add more details from the Specifications.

First, What's the difference between passing by reference vs. passing by value?

Passing by reference means the called functions' parameter will be the same as the callers' passed argument (not the value, but the identity - the variable itself).

Pass by value means the called functions' parameter will be a copy of the callers' passed argument.

Or from wikipedia, on the subject of pass-by-reference

In call-by-reference evaluation (also referred to as pass-by-reference), a function receives an implicit reference to a variable used as argument, rather than a copy of its value. This typically means that the function can modify (i.e. assign to) the variable used as argument—something that will be seen by its caller.

And on the subject of pass-by-value

In call-by-value, the argument expression is evaluated, and the resulting value is bound to the corresponding variable in the function [...]. If the function or procedure is able to assign values to its parameters, only its local copy is assigned [...].

Second, we need to know what Java uses in its method invocations. The Java Language Specification states

When the method or constructor is invoked (§15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared type, before execution of the body of the method or constructor.

So it assigns (or binds) the value of the argument to the corresponding parameter variable.

What is the value of the argument?

Let's consider reference types, the Java Virtual Machine Specification states

There are three kinds of reference types: class types, array types, and interface types. Their values are references to dynamically created class instances, arrays, or class instances or arrays that implement interfaces, respectively.

The Java Language Specification also states

The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.

The value of an argument (of some reference type) is a pointer to an object. Note that a variable, an invocation of a method with a reference type return type, and an instance creation expression (new ...) all resolve to a reference type value.

So

public void method (String param) {}
...
String var = new String("ref");
method(var);
method(var.toString());
method(new String("ref"));

all bind the value of a reference to a String instance to the method's newly created parameter, param. This is exactly what the definition of pass-by-value describes. As such, Java is pass-by-value.

The fact that you can follow the reference to invoke a method or access a field of the referenced object is completely irrelevant to the conversation. The definition of pass-by-reference was

This typically means that the function can modify (i.e. assign to) the variable used as argument—something that will be seen by its caller.

In Java, modifying the variable means reassigning it. In Java, if you reassigned the variable within the method, it would go unnoticed to the caller. Modifying the object referenced by the variable is a different concept entirely.


Primitive values are also defined in the Java Virtual Machine Specification, here. The value of the type is the corresponding integral or floating point value, encoded appropriately (8, 16, 32, 64, etc. bits).


Java always passes arguments by value NOT by reference.


Let me explain this through an example:

public class Main{
     public static void main(String[] args){
          Foo f = new Foo("f");
          changeReference(f); // It won't change the reference!
          modifyReference(f); // It will modify the object that the reference variable "f" refers to!
     }
     public static void changeReference(Foo a){
          Foo b = new Foo("b");
          a = b;
     }
     public static void modifyReference(Foo c){
          c.setAttribute("c");
     }
}

I will explain this in steps:

  1. Declaring a reference named f of type Foo and assign it to a new object of type Foo with an attribute "f".

    Foo f = new Foo("f");
    

  2. From the method side, a reference of type Foo with a name a is declared and it's initially assigned to null.

    public static void changeReference(Foo a)
    

  3. As you call the method changeReference, the reference a will be assigned to the object which is passed as an argument.

    changeReference(f);
    

  4. Declaring a reference named b of type Foo and assign it to a new object of type Foo with an attribute "b".

    Foo b = new Foo("b");
    

  5. a = b is re-assigning the reference a NOT f to the object whose its attribute is "b".


  6. As you call modifyReference(Foo c) method, a reference c is created and assigned to the object with attribute "f".

  7. c.setAttribute("c"); will change the attribute of the object that reference c points to it, and it's same object that reference f points to it.

I hope you understand now how passing objects as arguments works in Java :)


Java has only pass by value. A very simple example to validate this.

public void test() {
    MyClass obj = null;
    init(obj);
    //After calling init method, obj still points to null
    //this is because obj is passed as value and not as reference.
}
private void init(MyClass objVar) {
    objVar = new MyClass();
}

Java is always pass-by-value. Unfortunately, they decided to call the location of an object a "reference". When we pass the value of an object, we are passing the reference to it. This is confusing to beginners.

It goes like this:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    // we pass the object to foo
    foo(aDog);
    // aDog variable is still pointing to the "Max" dog when foo(...) returns
    aDog.getName().equals("Max"); // true
    aDog.getName().equals("Fifi"); // false 
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // change d inside of foo() to point to a new Dog instance "Fifi"
    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}

In the example above aDog.getName() will still return "Max". The value aDog within main is not changed in the function foo with the Dog "Fifi" as the object reference is passed by value. If it were passed by reference, then the aDog.getName() in main would return "Fifi" after the call to foo.

Likewise:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    foo(aDog);
    // when foo(...) returns, the name of the dog has been changed to "Fifi"
    aDog.getName().equals("Fifi"); // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // this changes the name of d to be "Fifi"
    d.setName("Fifi");
}

In the above example, Fifi is the dog's name after call to foo(aDog) because the object's name was set inside of foo(...). Any operations that foo performs on d are such that, for all practical purposes, they are performed on aDog itself (except when d is changed to point to a different Dog instance like d = new Dog("Boxer")).


Java is always pass by value, with no exceptions, ever.

So how is it that anyone can be at all confused by this, and believe that Java is pass by reference, or think they have an example of Java acting as pass by reference? The key point is that Java never provides direct access to the values of objects themselves, in any circumstances. The only access to objects is through a reference to that object. Because Java objects are always accessed through a reference, rather than directly, it is common to talk about fields and variables and method arguments as being objects, when pedantically they are only references to objects. The confusion stems from this (strictly speaking, incorrect) change in nomenclature.

So, when calling a method

  • For primitive arguments (int, long, etc.), the pass by value is the actual value of the primitive (for example, 3).
  • For objects, the pass by value is the value of the reference to the object.

So if you have doSomething(foo) and public void doSomething(Foo foo) { .. } the two Foos have copied references that point to the same objects.

Naturally, passing by value a reference to an object looks very much like (and is indistinguishable in practice from) passing an object by reference.


Java passes references by value.

So you can't change the reference that gets passed in.


Java passes references to objects by value.


Let me try to explain my understanding with the help of four examples. Java is pass-by-value, and not pass-by-reference

/**

Pass By Value

In Java, all parameters are passed by value, i.e. assigning a method argument is not visible to the caller.

*/

Example 1:

public class PassByValueString {
    public static void main(String[] args) {
        new PassByValueString().caller();
    }

    public void caller() {
        String value = "Nikhil";
        boolean valueflag = false;
        String output = method(value, valueflag);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'value' and 'valueflag'
         */
        System.out.println("output : " + output);
        System.out.println("value : " + value);
        System.out.println("valueflag : " + valueflag);

    }

    public String method(String value, boolean valueflag) {
        value = "Anand";
        valueflag = true;
        return "output";
    }
}

Result

output : output
value : Nikhil
valueflag : false

Example 2:

/** * * Pass By Value * */

public class PassByValueNewString {
    public static void main(String[] args) {
        new PassByValueNewString().caller();
    }

    public void caller() {
        String value = new String("Nikhil");
        boolean valueflag = false;
        String output = method(value, valueflag);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'value' and 'valueflag'
         */
        System.out.println("output : " + output);
        System.out.println("value : " + value);
        System.out.println("valueflag : " + valueflag);

    }

    public String method(String value, boolean valueflag) {
        value = "Anand";
        valueflag = true;
        return "output";
    }
}

Result

output : output
value : Nikhil
valueflag : false

Example 3:

/** This 'Pass By Value has a feeling of 'Pass By Reference'

Some people say primitive types and 'String' are 'pass by value' and objects are 'pass by reference'.

But from this example, we can understand that it is infact pass by value only, keeping in mind that here we are passing the reference as the value. ie: reference is passed by value. That's why are able to change and still it holds true after the local scope. But we cannot change the actual reference outside the original scope. what that means is demonstrated by next example of PassByValueObjectCase2.

*/

public class PassByValueObjectCase1 {

    private class Student {
        int id;
        String name;
        public Student() {
        }
        public Student(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Student [id=" + id + ", name=" + name + "]";
        }
    }

    public static void main(String[] args) {
        new PassByValueObjectCase1().caller();
    }

    public void caller() {
        Student student = new Student(10, "Nikhil");
        String output = method(student);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'student'
         */
        System.out.println("output : " + output);
        System.out.println("student : " + student);
    }

    public String method(Student student) {
        student.setName("Anand");
        return "output";
    }
}

Result

output : output
student : Student [id=10, name=Anand]

Example 4:

/**

In addition to what was mentioned in Example3 (PassByValueObjectCase1.java), we cannot change the actual reference outside the original scope."

Note: I am not pasting the code for private class Student. The class definition for Student is same as Example3.

*/

public class PassByValueObjectCase2 {

    public static void main(String[] args) {
        new PassByValueObjectCase2().caller();
    }

    public void caller() {
        // student has the actual reference to a Student object created
        // can we change this actual reference outside the local scope? Let's see
        Student student = new Student(10, "Nikhil");
        String output = method(student);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'student'
         */
        System.out.println("output : " + output);
        System.out.println("student : " + student); // Will it print Nikhil or Anand?
    }

    public String method(Student student) {
        student = new Student(20, "Anand");
        return "output";
    }

}

Result

output : output
student : Student [id=10, name=Nikhil]

No, it's not pass by reference.

Java is pass by value according to the Java Language Specification:

When the method or constructor is invoked (§15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared type, before execution of the body of the method or constructor. The Identifier that appears in the DeclaratorId may be used as a simple name in the body of the method or constructor to refer to the formal parameter.


The distinction, or perhaps just the way I remember as I used to be under the same impression as the original poster is this: Java is always pass by value. All objects( in Java, anything except for primitives) in Java are references. These references are passed by value.


To make a long story short, Java objects have some very peculiar properties.

In general, Java has primitive types (int, bool, char, double, etc) that are passed directly by value. Then Java has objects (everything that derives from java.lang.Object). Objects are actually always handled through a reference (a reference being a pointer that you can't touch). That means that in effect, objects are passed by reference, as the references are normally not interesting. It does however mean that you cannot change which object is pointed to as the reference itself is passed by value.

Does this sound strange and confusing? Let's consider how C implements pass by reference and pass by value. In C, the default convention is pass by value. void foo(int x) passes an int by value. void foo(int *x) is a function that does not want an int a, but a pointer to an int: foo(&a). One would use this with the & operator to pass a variable address.

Take this to C++, and we have references. References are basically (in this context) syntactic sugar that hide the pointer part of the equation: void foo(int &x) is called by foo(a), where the compiler itself knows that it is a reference and the address of the non-reference a should be passed. In Java, all variables referring to objects are actually of reference type, in effect forcing call by reference for most intends and purposes without the fine grained control (and complexity) afforded by, for example, C++.





pass-by-value