Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is mutating object-parameters in a method(in Java) a bad practice?

I have a question about mutating method-paramaters(which are objects) in a method.

I read and heard multiple times that it is a bad practice to mutate a object in a method which was passed in as a paramater. As example:

public void modifyList(List<Object> list) {
    list.add(new Object());
}

Instead, the passed in Object should be copied, the mutation should be performed on the copied object and the copied object should be returned. As example:

public List<Object> getModifiedList(List<Object> list) {
    List copy = new List<Object();
    //Make a deep copy if it would be necessary
    for(Object o : list) {
        copy.add(o.clone());
    }
    //Modify the copy
    copy.add(new Object());
    //return the copy
    return copy;
}

I understand that the second method has less potential for side effects because it doesn't mutate the input parameter.

But is this really the way to go? The performance would suffer because a lot of deep copys have to be created. Also it would cost a lot of time implement Copy-Constructors and implement clone-methods for all classes. Also it would increase the LOC immense.

In practice I don't see this pattern(copy the method-parameter) often.

Could somebody with a lot of experience(working as a programmer/software developer for years) answer this?

Greetings Maverin

like image 362
MaverinCode Avatar asked Aug 28 '18 14:08

MaverinCode


People also ask

Why is mutating objects bad?

Mutation may lead to unexpected and hard-to-debug issues, where data becomes incorrect somewhere, and you have no idea where it happens. Mutation makes code harder to understand: at any time, an array or object may have a different value, so we need to be very careful when reading the code.

Can you modify parameters in Java?

Unlike many other languages, Java has no mechanism to change the value of an actual parameter.

Why must we be careful when passing a mutable object to a function?

Both Dictionary and List in python are mutable, therefore caution should be taken when passed as an argument to functions because they are passed by reference and not by value, meaning that when passed to a function as an argument the object is referenced and a copy of the object is not created which might cause a bug ...

How do you mutate an object in Java?

Abstract: Mutation analysis inserts faults into a program to create test sets that distinguish the mutant from the original program. Inserted faults must represent plausible errors. Standard transformations can mutate scalar values such as integers, floats, and character data.


2 Answers

Both methods are fine and could be the correct choice depending on your use case. Just make sure that you name them in a way that makes the intent clear and write some javadoc.

It's then up to the developer to decide whether having the original list mutated is ok or not, and if not, pass a copy or use a different method.

For example, this method from the JDK mutates an existing list, but its intent and documentation are very clear.

like image 145
assylias Avatar answered Nov 10 '22 10:11

assylias


It's up to your use-case, as you have already implied. Making your components immutable brings many advantages such as better encapsulation, thread safety, avoiding having invalid state etc.. Of course, in this way you implement a performance hit. But someone with great experience wrote a chapter about this, which I can only recommend:

Effective Java -

Item 50: Make defensive copies when needed.

There he recommends:

You must program defensively, with the assumption that clients of your class will do their best to destroy its invariants.

and also:

In summary, if a class has mutable components that it gets from or returns to its clients, the class must defensively copy these components. If the cost of copy would be prohibitive and the class trusts its clients not to modify the components inappropriately, then the defensive copy may be replaced by documentation outlining the client's responsibility not to modify the affected components.

like image 43
Eirini Graonidou Avatar answered Nov 10 '22 08:11

Eirini Graonidou