Could pass object as function parameter and reassign it in function to modify its value out of function scope in java?

I think this is a common confusion over pass-by-value in Java.

If you want to think of it in terms of a rule: if you pass an object (reference) to a method, you cannot change which object is passed in. Put another way, you cannot change that reference to another object.

What you ARE able to do is change things WITHIN the object -- your f3 method above should change the things within the object passed to it just fine.

But you cannot -- as it appears you are trying to do in f2 -- change the object passed in (ojb in class A) to another object. To return an object from a method, it either has to be returned in the method's return statement, or it has to be a field in another object so that it can be changed within the other object.

Now, if you want the lower-level explanation, instead of the rule:

When you put an object variable name as a parameter to a method in Java, you are passing a 'pointer to' that object. You can think of it as the object being represented by its address in memory, and that you are passing a variable that holds that address. And you can think of the variable holding the address of the object as being passed by value, even though you are passing the OBJECT by reference.

The method gets the parameter as a special kind of variable, and can refer to that object with the parameter variable. And the method can change the variable; what it cannot do is change it for the caller.

Take your method from above:

void f2(Obj o) {
    List<Integer> l1 = new ArrayList<Integer>(){{
                        add(1);
                        add(2);
                        add(3);
                          }};
    Obj o2 = new Obj(10.0, true, false, l1);
    o = o2;
}

A caller passes in a parameter 'variable' containing a pointer to an object; the f2 method calls that parameter variable o. f2 can change the value of the parameter variable. But whatever object resided at that address still resides at that address, and any variables in the caller holding that address still hold that address.

Another way of looking at it: let's say the caller passes in a variable called george to your f2 method:

SomeObject george = new SomeObject();
f2(george);

and let's say that george is at address 1234. We could then think of o in f2 as holding 1234, the address of george. f2 creates a new object with Obj o2 = new Obj(10.0, true, false, l1);, let's say o2 is at address 5678. What the statement o = o2 in your f2 does is assign 5678 to o, replacing the 1234 that used to be there. This does not affect the caller; george is still at 1234. f2 changed a variable holding george's address, but the caller doesn't have a way to know that.


While invoking a method with primitive types (byte, short, char, int, long, float, double, boolean) values are passed, with objects - references.

In other words, it's impossible to change the initial value of a primitive variable like int by passing it as an argument while calling a method. But it's doable with an object, but only in the case if it's a mutable object. For example, you can an instance of your custom class Obj or instance of StringBuilder, but you cant change a BigInteger or String, these classes are designed to be immutable.

https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html