Why use get and set in Java?

I learned in college a while ago that I should always use getters and setters to access values in an object and I heard that it is for security reasons.

So I ended up always using and seeing other people using, until I started programming Android and noticed that Google says to not use, for performance reasons (only in the case of Android).

So what is get and set for? Is it only for good practice? I did not understand why good practice in this case. What influences me to use or not?

Is the security question true? It seems kind of logical to say this.

Example:

pessoa.getNome(); //acessando uma variavel privada com get

pessoa.nome; //acessando uma variavel publica diretamente
Author: Maniero, 2014-11-14

3 answers

"security" in this case refers only to a programmer accidentally accessing a variable in a different way than the one intended by the class author (not necessarily a different programmer). I will give an example:

class Fração {
    int numerador;
    int denominador; // Não pode ser zero

    public int calcular() { return numerador / denominador; }
}

If you can access the variables directly, you need to always remember that denominador cannot be zero. But what if you forget? Right now, nothing's gonna happen... But times later, when another part of the code calls calcular, it will give a division error by zero. In an hour that you are not waiting for, and it will seem that it was the call to the calculation that caused the exception (making it more difficult to debug).

Now, let's say you change the visibility of this variable to private and create a getter and a setter :

class Fração {
    int numerador;
    private int denominador; // Não pode ser zero

    public int getDenominador() {
        return denominador;
    }

    public void setDenominador(int denominador) {
        if ( denominador == 0 )
            throw new IllegalArgumentException("O denominador não pode ser zero!");
        this.denominador = denominador;
    }

    public int calcular() { return numerador / denominador; }
}

In this case, you Continue having to remember that you cannot pass zero, but what if you forget, what changes? Changes that the exception will be thrown immediately when trying assign the value by pointing to the exact line of code where the error occurred, so that it becomes much easier to identify and fix the error.

Note that in the case of numerador, it makes no sense to create getter and setter, you can do it (by convention) or not.

There are other benefits of having an extra layer of abstraction around your variables, for example allowing you to change the internal representation of your class by keeping your contract constant. It benefits are most significant when you want to have a stable API, or when you program on a large team where not everyone knows exactly what the other's code does.

In general, the loss of performance in using one more method is negligible compared to the benefits that this technique brings. However, if you are always creating getters and setters "because I learned that's how it has to be", but you never or rarely need to validate a field, or refactor the implementation, or you have no one but yourself consuming your API, then the thing changes: not only do you spend more time writing a lot of useless code, as the small losses in performance throughout the project accumulate, which can give a significant difference (I doubt, it seems to me micro-optimization, but you will know... maybe Android Java is not as optimized to handle this case as the official JVM).

I think that's the reason behind this recommendation not to use on Android. Does the code become "less secure"? Be. But it's just a matter of being more careful when programming (and this is always "good practice"). As for the final product, this alone does not cause any vulnerabilities in the code or anything like that.

 20
Author: mgibsonbr, 2014-11-14 09:39:47

The use of get and set methods is practiced for security reasons. The method applied in this case is encapsulation. The goal in fact is not to allow variables to be modified directly. For example, let's imagine the following possible class structure:

public class Ponto {
    public int x;
    public int y;

    public Ponto(){}

   // métodos da classe.
}

From the moment you instantiate the point object, you have direct access to the variables x and y. The most common thing to do in these cases is to change the visibility of the variable, usually using "private "instead of"public". Soon after comes the adorable gets and sets. With the use of the gets and sets you start to allow a private visibility variable to be accessed. Let's go to another example:

public class Ponto {
    private int x;
    private int y;

    public Ponto(){}

    public int setX(int valor){
       this.x = valor;
    }

    public int getX(){
       return this.x;
    }


   // métodos da classe.
}

In the example above, only through the methods getX and setX is it possible to manipulate the variable X, while the variable Y because it does not have get and set cannot be accessed directly. Now the most important part. it makes no sense to create classes with variables of private visibility if you are going to create for all of them (variables) the get and set. Now, if the purpose of private is to make access impossible, what sense does it make to use get and set if they give direct access to the variable? But why do we actually use it? simple, by standardization, but we must use in a moderate way. For the reasons already mentioned.

Hug.

 9
Author: touchmx, 2014-11-14 13:15:36

Being short and thick... If all your accessor get does is return a field from the class, and all your accessor set does is change the value of that field, type like this:

public class Pessoa {
    private int _idade;

    public int getIdade() { return _idade; }
    public void setIdade(value) { _idade = value; }
}

...Maybe you should make your camp public.

This does not give any security. If there is performance consideration, it is because your execution stack gets one level higher to handle the value of the age variable.

Another security consideration is that there is a programming called reflection . I leave it to you to research on this, but in summary: making a variable private does not mean that it cannot be read or changed directly by other classes. You just made these operations more expensive in terms of processing.

Accessors are methods and as such serve to execute some logic that is of interest to you. For example, assuming you have a property by reference, such as a list. Let's give our class Person A list of children:

public class Pessoa {
    public List<Pessoa> filhos;
}

If you try to access this property on an instance, you may receive a NULL pointer error.

Pessoa p = new Pessoa();
p.filhos.Add(new Pessoa()); // você acessou uma variável nula.

Now let's make a really useful accessory. Please assure the user of our API that they will be able to access a guaranteed instantiated list, as follows:

public class Pessoa {
    private List<Pessoa> _filhos;
    public List<Pessoa> getFilhos() {
        if (this._filhos == null) {
            this._filhos = new List<Pessoa>();
        }
        return this._filhos;
    }
}

Now this will never give null pointer error:

Pessoa p = new Pessoa();
p.getFilhos.Add(new Pessoa());

The idea behind the accessors is this: a series of operations required to read or write values for the class is encapsulated in them.

The security of accessors therefore depends on what is implemented in them. In cases like the example I used, the security is in avoiding a NULL pointer exception. Other security aspects may involve checking permissions, preventing divisions by zero, ensuring that file access will not cause lock in those files, etc.

 7
Author: Garoto de Programa, 2014-11-14 13:36:51