They absolutely are evil.
@coobird unfortunately they absolutely do not "enforce the concept of encapsulation", all they do is make you think you're encapsulating data when in fact you're exposing data via a property with delusions of method grandeur. Anything a getter/setter does a public field does better.
First, if you want public data, make it public, get rid of the getter & setter methods to reduce the number of methods the client has to wade through and make it cognitively simpler for the client to change it's value by eg.
object.field = value;
instead of the more cognitively intense
object.setField(value);
where the client must now check the getter/setter method to see if it has any side-effects.
Second, if you really need to do something else in the method, why call it a get/set method when it's got more responsibilities than simply getting or setting?
Either follow the SRP or call the method something that actually tells you what the whole method does like Zarkonnen's examples he mentioned eg.
public void kill(){
isAlive = false;
removeFromWorld(this);
}
instead of
public void setAlive(boolean isAlive){
this.isAlive = isAlive;
if (isAlive)
addToWorld(this);
else
removeFromWorld(this);
}
where does the setAlive(boolean) method tell the client that as a side-effect it'll remove the object from the world? Why should the client have any knowledge about the isAlive field? Plus what happens when the object is re-added to the world, should it be re-initialised? why would the client care about any of that?
IMHO the moral is to name methods to say exactly what they do, follow the SRP and get rid of getters/setters.
If there's problems without getters/setters, tell objects to do their own dirty work inside their own class instead of trying to do things with them in other classes.
here endeth my rant, sorry about that ;)