Вопрос

I have created an object which has a getter that returns a map. When ever I call getter and change the map from a calling object, why does it effect the original map. Even if it is declared as final. Why does this happen.

1>Is it because instead of returning a map object does the getter returns only object reference? 2>Does this happens to lists too?

Below code just for example not perfect code.

public class Worker{
private final Map<String, String> work;


public MatcherManager(Map<String, String> input) {
    checkNotNull(input, "Input map not found");
    his.workExperienceMatcher = input;
}

public Map<String, String> getWork() {
    return work;
}
Это было полезно?

Решение 2

By returning the same map, the outside world now gets a handle (in other words, reference) to mutate the map.

If you do not desire such a behaviour, you could return another reference instead:

public Map<String, String> getWork() {
    return new HashMap<String, String>(work);
}

The evil, outside world can now only mutate this new reference - and it will have no impact on the underlying work map.

And yes, the same theory applies for other collection classes such as lists and sets as well.

Другие советы

You said it yourself - "1>Is it because instead of returning a map object does the getter returns only object reference?" .

Yes,in Java everything is manipulated using references to objects

. You are getting the reference of the map, changing it.. Even though you have declared it as "final", final and immutability are 2 different things.. final means , "you can't change the reference", immutability means - "you can't change the value of the object". By declaring a non-primitive variable as final, you are saying - "I will not make this reference point to anything else. But I can change the properties of the object to which my reference points." . for primitives, you cant change the value of a final variable. Immutability is not a built in feature in Java. Immutability can be achieved by providing only "public getters", not setters. Immutablity prevents changing of value of an object. final prevents changing of reference. Remember- - "In Java references are passed by value".

In case you want unmodifiable/immutable list, you can use

Collections.unmodifiableList

check out - Java Immutable Collections

You're returning an object reference which points to the same memory addresses as the original map. So when you make a change to the particular values in the map, you are updating the values that both maps are pointing to. This is true for lists as well. A map that is declared final cannot have a new map assigned to it, but the values in a final map can be updated.

Yes what is being passed is a reference to the original object. So the changes you do to the returned object, affects the original.

Java uses 'pass by value' mechanism. However when it comes to objects what is passed is a copy of the reference to the object. So changes you do via the returned reference affects the original object. However when it comes to primitives what is passed is a real copy therefore changes you do to primitives don't affect the original.

1>Is it because instead of returning a map object does the getter returns only object reference? yes,final only decorate physics address.It does not care about the value.so you can change the value of the refernce. 2>Does this happens to lists too? yes,it's the same principle.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top