Author Topic: In Java, EVERYTHING is passed by value.  (Read 7900 times)

0 Members and 1 Guest are viewing this topic.

Offline Ender

  • x86
  • Hero Member
  • *****
  • Posts: 2390
    • View Profile
In Java, EVERYTHING is passed by value.
« on: February 19, 2007, 09:28:42 pm »
Unlike other languages like C/C++, Java passes everything by value. You may say, "wait, when I pass an object it passes it by reference". Wrong. You never pass the object itself. You pass a reference to that object. And you pass the reference to that object by value.

Consider the following example:
Code: [Select]
public class Example {
       public void changeWhichSocketTheWholeProgamUses(Socket original, Socket new) {
              original = new; // DOESN'T WORK
       }
}

original and new are references to different Socket objects. Even though they are references, they are passed by value. When you pass something by value, you create a clone of the value in another memory space. Thus, when you change the value of that memory space, you only change that memory space, not the memory space that you cloned previously.

So if a program were using a single socket and you wanted to pass a reference to that socket in order to switch the entire program to another socket, you can't do that. It will work in the class/method that changes the socket, but it won't work in other classes, because you're creating an alternate memory space and storing the reference value there, instead of altering the memory space that all the other objects in the program refer to.

The common way that Java people do something like the example code above is through Singletons. In other languages like C/C++ you can actually pass references by reference.

A way that I like to visualize it is by arrows. The arrows are the references and the memory is contained within |'s.

Here's what you do in Java:

|reference value (address)| -----> |object memory|

It's a reference to an object. The first memory slot is the value of the reference, which is passed. When you dereference the reference, using the '.' operator, you can modify the data in the second memory slot.

Here's what you can do in languages like C/C++ that you can't do in Java.

|reference value (address)| ------> |reference value (address)| -------> |object memory|

It's a reference to a reference to an object. You can do the global socket change that was given above in C++ by passing a reference to a reference and modifying the address of the second reference.

In Java, you try to avoid global reference changes, but if you can't then what you normally do is you have an object (a Singleton) that maintains a reference to another object. I'll give an example of a Singleton below:

Code: [Select]
public class Singleton {
     
     private static Singleton singleton;   
 
     public static void getInstance()
     {
           if (singleton == null) {
                 singleton = new Singleton();
           }
            return singleton;
     }

      public static void globalReferenceChange(Singleton newSingleton) {
              singleton = newSingleton;
      }
}

Offline shift

  • Newbie
  • *
  • Posts: 1
    • View Profile
Re: In Java, EVERYTHING is passed by value.
« Reply #1 on: November 01, 2007, 04:55:10 am »
Misinformation is tainted information.

As an example, let's see if we pass the "values" of an array, or the reference to the array in a test case...
Code: [Select]
public final class ArrayTest {
    public static void test(int array[]) {
        array[0] = 6;
    }

    public static void main(String args[]) {
        int tvar[] = new int[] {0, 1, 2, 3, 4, 5};

        test(tvar);

        for(int i : tvar) {
            if(i == 6) {
                System.out.println("Point proven.");
                break;
            }
        }
    }
}
As you can see through execution, the point gets proven... If it passed only the value, then me assigning to that "value" wouldn't change it for the original method, thus proving your statements incorrect.


In second case, I refer you to Java's own specifications, opcode 0x01, mnemonic [tex]ACONST-NULL[/tex]
Quote from: JVM Specs
Push the null object reference onto the operand stack.

Notice the wording, reference.

Offline Ender

  • x86
  • Hero Member
  • *****
  • Posts: 2390
    • View Profile
Re: In Java, EVERYTHING is passed by value.
« Reply #2 on: November 01, 2007, 10:38:18 am »
lolol ::)

You are wrong. Nice try. Come again.

Offline Ender

  • x86
  • Hero Member
  • *****
  • Posts: 2390
    • View Profile
Re: In Java, EVERYTHING is passed by value.
« Reply #3 on: November 01, 2007, 11:00:12 am »
To be more specific...

First I will note that after this post, I am not going to argue this further, since I have a lot of work to do this week.

In your first example, you are passing the reference of the array by value. Thus you end up calling array[0].value = newValue; Since the memory cell for the variable in the method reads the same address as the memory cell of the variable outside the method, you are referencing the same object in both cases. Thus when you ask the object what it's value is at the 0-index, it will tell you the same answer. If you were to say tvar = new int[10]; then you change the address in the local variable but you don't change the address outside that, since you are dealing with different memory cells.

In your second example, the "by value" is implied, since everything is passed by value. And we both know that if you pass a reference myRef to a method, and in that method you say myRef = blah; then it doesn't affect the original reference elsewhere in that program.

Corroboration:

http://javadude.com/articles/passbyvalue.htm
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
http://www.javaranch.com/campfire/StoryPassBy.jsp
http://www.jguru.com/faq/view.jsp?EID=430996
http://www.ibm.com/developerworks/java/library/j-passbyval/

As you see, some widely-regarded authorities on Java and programming, such as javaworld, javaranch, and IBM, agree.
« Last Edit: November 01, 2007, 11:07:33 am by Ender »

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
Re: In Java, EVERYTHING is passed by value.
« Reply #4 on: November 01, 2007, 12:14:41 pm »
Doesn't C do the same thing? That is, references (& modifier) are just subtle pointers? Or am I wrong, and the calling function will see modifications to the local copy of the pointer? When we went over references in my C class, I just used pointers instead. When the professor asked me why I did that, my answer was "because references are stupid; they just boil down to pointers anyways," which he accepted. Perhaps I was wrong?

In any event, it's important to make a few notes on this topic:

First, calling methods on the object will affect state of the object, if the method changes the state of the object, not the reference to the object. Don't confuse something like String.concat(String) for one of these methods; the statement "String1.concat(String2)" is equivalent to "String1 + String2," and does not affect the state of String1 or String2; it creates a new String object and returns it. Modifying the object (ex: <String> += "hello") will change the reference to the object, and not the state of the original objects. Base types are not objects, and can't be referenced in Java, so this rule doesn't apply to them. Despite this exception, base types still behave according to the same rules that Objects do, if you apply the rules for references to base types' states. Just think about it, they're the same thing: when you pass an object reference, you PUSH and pointer to its location; when you pass a base type you PUSH its value.

Second, it's totally tabu to modify method parameters inside the method! They are not to be considered equals with local variables. The compiler even provides a flag for generating warnings or errors when method parameters are modified, even though it's not the default behavior any more. This whole argument is a corner-case to something Sun would likely consider a hack. This has always been the behavior of Java, but in the beginning it wasn't defined because it wasn't expected to occur.

Third, this discussion is kind of pointless. If your assumptions are faulty, and you encounter this fact of Java, it's immediately obvious to anyone who knows how to use a debugger what's happening.

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!

Offline Ender

  • x86
  • Hero Member
  • *****
  • Posts: 2390
    • View Profile
Re: In Java, EVERYTHING is passed by value.
« Reply #5 on: November 01, 2007, 04:15:26 pm »
Oy, vey. Looks like I will have to respond to this thread again after all.

1.
In any event, it's important to make a few notes on this topic:

No, not really.

2. Who are you talking to, me or shift?

3. Are you shift? It's weird for a stranger to make a first post like that.

4. What's your main point? Do you agree that everything in Java is passed by value? Do you agree but think this statement is pointless?

Offline iago

  • Leader
  • Administrator
  • Hero Member
  • *****
  • Posts: 17914
  • Fnord.
    • View Profile
    • SkullSecurity
Re: In Java, EVERYTHING is passed by value.
« Reply #6 on: November 01, 2007, 06:43:40 pm »
I don't know if anybody said this already, but this is just a semantic thing. No matter what you're passing in any language, you're always passing something by value, be it the object or the object's address. In Java, you're passing a reference to the object (essentially, the object's address).

Offline Camel

  • Hero Member
  • *****
  • Posts: 1703
    • View Profile
    • BNU Bot
Re: In Java, EVERYTHING is passed by value.
« Reply #7 on: November 02, 2007, 11:29:10 am »
2. Who are you talking to, me or shift?

3. Are you shift? It's weird for a stranger to make a first post like that.

4. What's your main point? Do you agree that everything in Java is passed by value? Do you agree but think this statement is pointless?

2: No one in particular, just making some simple observations.

3: No.

4: I mostly agree with iago, except that in C, you can't directly see the value being PUSHed on to the stack unless you use a pointer/base type, or get the address of the reference. In Java, there's no distinction between references and pointers. As iago said, it's all just semantics, though. Anyone who has even a basic understanding of what pointers are should not ever be confused by this behavior in any language. C programmers, especially, should make an effort to understand them.

<Camel> i said what what
<Blaze> in the butt
<Camel> you want to do it in my butt?
<Blaze> in my butt
<Camel> let's do it in the butt
<Blaze> Okay!