Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
225 views
in Technique[技术] by (71.8m points)

java - Why make defensive copies in getters inside immutable classes?

This question is about good programming practices and avoiding potential holes.
I read Joshua Bloch's Effective Java and here is what I wonder:
Why should I consider making defensive copies in getter methods in my immutable class with no mutators in it?
And second: why should I make my fields final in addition to private ? Is this only about performance (not security) ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I believe this is the case that justifies this statements:

public class Immutable {

    private final String name;

    private Date dateOfBirth;

    public Immutable(String name, Date dateOfBirth) {
        this.name = name;
        this.dateOfBirth = dateOfBirth;
    }

    public String getName() {
        return name;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

}

getName() is fine as it returns immutable object as well. However the getDateOfBirth() method can break immutability because the client code can modify returned object, hence modifying the Immutable object as well:

Immutable imm = new Immutable("John", new Date());

imm.getName(); //safe
Date dateOfBirth = imm.getDateOfBirth();
//hundreds of lines later
dateOfBirth.setTime(0);  //we just modified `imm` object

It is safe to return immutable objects and primitives (as they are returned by value). However you need to make defensive copies of mutable objects, like Date:

public Date getDateOfBirth() {
    return new Date(dateOfBirth.getTime());
}

and wrap collections in immutable views (if they are mutable), e.g. see Collections.unmodifiableList():

public List<Integer> getSomeIds() {
    return Collections.unmodifiableList(someIds);
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...