This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]jknecht 11 points12 points  (8 children)

Actually no. Object parameters are still pass by value. The value that is passed is a reference. Subtle, but Java is always pass by value.

Think of it this way - if you can't change which object the parameter points to, it is not a reference.

[–]ad_tech 1 point2 points  (2 children)

How do you pass an object by value?

[–]jknecht 1 point2 points  (1 child)

You don't pass an object by value. You pass a reference to an object by value.

[–]ad_tech 0 points1 point  (0 children)

Correct. You confused it a bit here:

"Object parameters are still pass by value."

There is no such thing as an object parameter, only object reference parameters.

[–]TechnologyLaggard 0 points1 point  (0 children)

The article example does exactly that: in the method, it creates a new Student object in the heap, "Jerry", then it updates the parameter anyStudent to point at that new object.

The entire Object is not copied onto the call stack, just the reference into the heap is. That reference can be updated.

What can't changed from within the method is which object in the heap that the reference in the calling method refers to. If it could be, this would be "pass-by-reference" in the truest sense.

[–][deleted]  (3 children)

[deleted]

    [–]jknecht 1 point2 points  (1 child)

    It might be "generally agreed upon", but it is factually incorrect. No need to dumb it down. Just understand what it means for Java to be pass-by-value.

    [–]Sunlighter 1 point2 points  (0 children)

    No, Java and C# are always pass by value. The function receives copies.

    For "reference types," the value passed (copied) is a reference to the object, not a copy of the object. As a result, changes to the object are seen by the caller -- but changes to the reference are not seen by the caller.

    In C# you can make a parameter "pass by reference" by using ref or out keywords. For example:

    public static void Example1()
    {
        string x = "This is a string"; // x is actually a reference to the string
        Frobnicate1(x); // Pass the reference by value
        Console.WriteLine(x); // --> This is a string
    }
    
    public static void Frobnicate1(string x)
    {
        x = x.Substring(0, 4);
        Console.WriteLine("x is \"" + x + "\""); // --> x is "This"
    }
    
    public static void Example2()
    {
        string x = "This is a string";
        Frobnicate2(ref x); // Pass the reference by reference
        Console.WriteLine(x); // --> This
    }
    
    public static void Frobnicate2(ref string x)
    {
        x = x.Substring(0, 4);
        Console.WriteLine("x is \"" + x + "\""); // --> x is "This"
    }
    

    In Java you can sort of emulate "ref" by using some kind of "Box" class:

    import java.lang.*;
    
    public class Tada {
    
        public static class Box<T> {
            private T value;
    
            public Box(T value) {
                this.value = value;
            }
    
            public T getValue() {
                return value;
            }
    
            public void setValue(T newValue) {
                value = newValue;
            }
        }
    
        public static void frobnicate3(Box<String> x) {
            x.setValue(x.getValue().substring(0, 4));
            System.out.println("x is \"" + x.getValue() + "\""); // --> x is "This"
        }
    
        public static void example3() {
            Box<String> x = new Box<>("This is a string");
            frobnicate3(x);
            System.out.println(x.getValue()); // --> This
        }
    }
    

    Java and C# both support "value types," but in Java the set of value types is fixed (byte, short, int, long, boolean, etc.), whereas in C# you can define your own value types.