Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Acessar atributo constante da classe de forma direta (sem uso de getter e setter)

Durante o video o professor cita que o acesso ao atributo "out" (System.out.println()) "é uma má prática" que acabou ficando na linguagem Java, já que o atributo esta declarado como public e o acessamos de forma direta.

Fui dar uma olhada nisso porque fiquei imaginando, "Será que eu posso mudar a referencia que esta salva nesse atributo (atribuir uma outra)?!" (Já sabendo que nao ia sair algo "legal" disso). Mas o Java é mais esperto e deixou o atributo como final (e eu aqui me achando o esperto pensando que ia "sacanear" a JVM).

Pois bem, ai veio a pergunta, realmente é "má pratica" deixar o acesso public a constantes (atributos com final), uma vez que esse valor nao pode ser mudado e qualquer regra de negocio pertinente a esse valor já seria implementada na sua inicialização (inclusive como é uma constante já fica garantido que somente em um lugar do código ocorrerá a atribuição de valores a esse atributo, no caso na sua declaração na classe ou no construtor da mesma)?

O uso de um getter nesse caso nao seria desnecessário e só complicaria o código já que ficaria algo assim "System.getOut().println()"?

Pergunto porque pode ser que seja necessário acessar o valor de uma constante, de uma classe (static) ou mesmo de uma instancia (algo gerado no construtor).

Obrigado desde já.

1 resposta
solução!

Oi Anderson, tudo bem?

Esta observação sempre rende muita conversa kkkkk Bom vou tentar dar algumas razões pelas quais é bom evitar o uso generalizado de atributos públicos, mesmo se forem final:

  • Fere o conceito de encapsulamento pois você está expondo atributos daquela classe. O ideal é que o código que usa deve conhecer a interface de uso e não detalhes internos da classe como atributos;

  • Por conhecer detalhes internos, o código que usa fica com alto acoplamento com a classe que expôs os atributos. Qualquer mudança que você queira fazer na forma que este dado for obtido, pode quebrar o seu código muito facilmente. Se você tiver um getter ou um método de acesso, você pode mudar a implementação que o código de fora não vai quebrar; -- Já parou pra pensar se eles resolvessem mudar o System.out o caos que seria?

  • Se você for usar este atributo com frameworks que usam a convenção de Java Beans, é necessário que você tenha um getter senão não consegue usar as facilidades fornecidas;

  • Um atributo finalpode sempre gerar mais trabalho para você verificar se ele é realmente imutável. Você pode estar se perguntando "Se eu coloco final ele já não é imutável? ". Aí é que está pode existir uma confusão aqui. Por exemplo, imagine o seguinte código:

public class Pagamento {
    public final Calendar dataPgto;
    // outros atributos...

    public Pagamento(Calendar dataPgto) {
        this.dataPgto = dataPgto;
    }

    // métodos
}

Aí na hora de usar você faz o seguinte:

public class PagaFuncionario {
    public static void main(String []args) {
        Calendar dataAtual = new GregorianCalendar(2019, Calendar.MARCH, 31);
        Pagamento pgtoMarco = new Pagamento(dataAtual);
        // ...
    }
}

Parece de boas mas você pode fazer:

public class PagaFuncionario {
    public static void main(String []args) {
        Calendar dataAtual = new GregorianCalendar(2019, Calendar.MARCH, 31);
        Pagamento pgtoMarco = new Pagamento(dataAtual);
        pgtoMarco.dataPgto = new GregorianCalendar(2019, Calendar.MARCH, 29); // Putz isso aqui não dá! Bacana!
        pgtoMarco.dataPgto.add(-2, Calendar.DAY_OF_MONTH); //Isso funciona!
    }
}

Outra coisa que também funciona:

public class PagaFuncionario {
    public static void main(String []args) {
        Calendar dataAtual = new GregorianCalendar(2019, Calendar.MARCH, 31);
        Pagamento pgtoMarco = new Pagamento(dataAtual);

        dataAtual.add(-2, Calendar.DAY_OF_MONTH);  // Vai mudar a data do Pagamento.dataPgto também
    }
}

Isto acontece porque o que é imutável é o valor daquele atributo. Se você tem um atributo que é do tipo referência, ou seja, guarda uma referência para um objeto, você precisa verificar se ele é realmente imutável. No caso acima, podemos ver que a classe Calendar não é, por isso e por outras coisas hoje temos a classe LocalDate que é realmente imutável. Desta forma ao olhar um atributo public e final é possível que você precise verificar se a imutabilidade foi realmente implementada, devolvendo cópias daquele objeto ou não, o que gera muito mais trabalho.

Estas são algumas razões pelas quais é bom evitar, se ficou mais alguma dúvida ou se não concordar é só falar!

Abraço!