Por que a palavra-chave 'final' é usada tão pouco na indústria? [fechadas]

14

Desde que descobri os poderes da palavra-chave final em Java há alguns anos, isso me ajudou a tornar meus códigos muito mais legíveis, já que as pessoas podem ver facilmente quais são as variáveis somente de leitura. Isso também pode dar um pequeno impulso ao JIT, e embora seja muito limitado, não pode ser prejudicial, especialmente ao segmentar dispositivos incorporados, como plataformas Android.

Mas, mais do que tudo, contribui para tornar um design mais robusto para alterações e orienta outros committers quando eles precisam modificar a base de código.

No entanto, enquanto navega em algum código-fonte do JDK, eu nunca tropecei nessa palavra-chave, seja para classes, métodos ou variáveis. O mesmo se aplica a vários sistemas que tive que revisar.

Existe algum motivo? É um paradigma de design comum deixar tudo mutável por dentro?

    
por Aurélien Ribon 14.09.2011 / 23:04
fonte

5 respostas

9

Eu suspeito que a razão pela qual você não vê isso é porque o JDK foi projetado para ser estendido (é a base a partir da qual todos os seus programas são construídos). Não seria incomum para o código do aplicativo fazer uso dele. Eu também não esperaria ver muito disso no código da biblioteca (como as bibliotecas também são projetadas para extensão).

Tente dar uma olhada em alguns bons projetos de código aberto e acho que você encontrará mais.

Por contraste com o que você está vendo em Java, no mundo .NET, eu ouvi o argumento muitas vezes que os clases devem ser sealed (semelhante ao final aplicado a uma classe) por padrão, e que o o desenvolvedor deve desmarcá-lo explicitamente.

    
por 14.09.2011 / 23:37
fonte
15

O problema com o uso de final para transmitir que algo é somente leitura é que ele realmente funciona apenas para tipos primitivos como int , char etc. Todos os objetos em Java são realmente referidos usando um (tipo ) ponteiro. Como resultado, quando você usa a palavra-chave final em um objeto, você está apenas dizendo que a referência é somente leitura, o objeto em si ainda é mutável.

Ele poderia ter sido usado mais se realmente tornasse o objeto somente leitura. Em C ++, é exatamente isso que o const faz e, como resultado, é uma palavra-chave muito mais útil e mais usada.

Um lugar onde eu uso a palavra-chave final é strongmente com parâmetros para evitar qualquer confusão criada por coisas como esta:

public void someMethod(FancyObject myObject) {
    myObject = new FancyObject();
    myObject.setProperty(7);
}
...
public static void main(final String[] args) {
    ...
    FancyObject myObject = new FancyObject();
    someOtherObject.someMethod(myObject);
    myObject.getProperty(); // Not 7!
}

Neste exemplo, parece óbvio porque isso não funciona, mas se someMethod(FancyObject) é grande e a confusão complicada pode surgir. Por que não evitá-lo?

Também faz parte dos padrões de codificação da Sun (ou da Oracle, eu acho).

    
por 14.09.2011 / 23:32
fonte
4

Concordo que a palavra-chave final melhora a legibilidade. Isso torna muito mais fácil entender quando um objeto é imutável. No entanto, em Java é extremamente detalhado, particularmente (na minha opinião) quando usado em parâmetros. Isso não quer dizer que as pessoas não devam usá-lo porque é detalhado, mas não o usam porque é detalhado.

Algumas outras linguagens, como scala, tornam muito mais fácil fazer declarações finais ( val ). Nessas linguagens, as declarações finais podem ser mais comuns que as variáveis.

Observe que há muitos usos diferentes da palavra-chave final. Sua postagem abrange principalmente os itens 2 e 3.

  1. final Classes (JLS 8.1.1.2)
  2. campos finais (JLS 8.3.1.2)
  3. Métodos finais (JLS 8.4.3.3)
  4. Variáveis finais (JLS 4.12.4)
por 15.09.2011 / 00:35
fonte
2

Bem, para começar, as convenções de código oficiais do Java não favorecem nem proíbem o uso específico de% código%. Ou seja, os desenvolvedores do JDK estão livres para escolher a maneira que preferirem.

Eu não consigo ler a mente deles, mas para mim, a preferência por usar ou não final tem sido uma questão de foco. Uma questão de se tenho tempo suficiente para me concentrar completamente no código ou não .

  • Digamos que, em um dos meus projetos, poderíamos gastar em média um dia em 100 linhas de código. Neste projeto, eu tive uma percepção distinta de final como um lixo que apenas obscurece coisas que já estão expressas claramente no código. Parece que os desenvolvedores do JDK também estão nessa categoria.

    Por outro lado, foi totalmente oposto em outro projeto, onde gastamos uma média hora em 100 linhas de código. Lá, eu me encontrei atirando em final como uma pistola mashine no meu e no código do outro - simplesmente porque era a maneira mais rápida de detectar uma intenção do cara que a escreveu antes de mim e, similarmente, a maneira mais rápida de comunicar intento próprio para o cara que vai trabalhar no meu código mais tarde.

It may also provide a little boost to the JIT, and while that's a very limited one, it can't harm

O raciocínio como acima é escorregadio. Otimização prematura pode prejudicar; Donald Knuth chega a chamá-la de "a raiz de todo o mal" . Não deixe isso te prender. Escreva um código estúpido .

    
por 15.09.2011 / 09:31
fonte
2

Recentemente, descobri a alegria do recurso "Salvar ações" no IDE do Eclipse. Eu posso forçá-lo a reformatar meu código, inserir faltando @Override anotações e fazer algumas coisas bacanas como remover parênteses desnecessários em expressões ou colocar final palavra-chave em todos os lugares automaticamente toda vez que eu atingir ctrl + S . Ativei alguns desses gatilhos e, rapaz, ajuda muito!

Descobrimos que muitos desses gatilhos agem como uma rápida verificação de sanidade para o meu código.

  • Eu pretendia substituir um método, mas a anotação não apareceu quando eu acessei ctrl + s ? - talvez eu estraguei os tipos de parâmetro em algum lugar!
  • Alguns parênteses foram removidos do código ao salvar? - talvez essa expressão lógica seja muito difícil para um programador se locomover rapidamente. Caso contrário, por que eu adicionaria esses parênteses em primeiro lugar?
  • Esse parâmetro ou variável local não é final . Ele tem para alterar seu valor?

Descobriu-se que quanto menos variáveis mudam, menos problemas eu tenho no tempo de depuração. Quantas vezes você estava seguindo o valor de alguma variável apenas para descobrir que de alguma forma muda de 5 para 7? "Como diabos poderia ser ?!" você se pergunta e passa algumas horas entrando e saindo de inúmeros métodos para descobrir que cometeu um erro em sua lógica. E para consertá-lo, você precisa adicionar mais uma bandeira, algumas condições e alterar cuidadosamente alguns valores aqui e ali.

Oh, eu odeio depurar! Cada vez que corro o depurador, sinto que o meu tempo está a esgotar-se e preciso desesperadamente de algum tempo para fazer, pelo menos, alguns dos meus sonhos de infância para se tornarem verdade! Para o inferno com depuração! final s significa que não há mais mudanças misteriosas de valor. Mais final s = > partes menos frágeis no meu código = > menos bugs = > mais tempo para fazer coisas boas!

Quanto a final classes e métodos, não me importo. Eu amo polimorfismo. Polimorfismo significa reutilização significa menos código significa menos bugs. A JVM faz um trabalho muito bom com a desvirtualização e o método inlining de qualquer maneira, portanto, não vejo valor em eliminar as possibilidades de reutilização de código para benefícios insanos de desempenho.

Ver todos os final s no código é um pouco perturbador no início e leva tempo para se acostumar também. Alguns dos meus colegas de equipe ainda ficam muito surpresos ao ver tantas palavras-chave final . Eu gostaria que houvesse uma configuração no IDE para uma coloração de sintaxe especial para ela. Eu ficaria feliz em mudá-lo para algum tom de cinza (como anotações) para que eles não fiquem muito distraídos ao ler o código. O Eclipse tem atualmente uma cor separada para return e todas as outras palavras-chave, mas não para final .

    
por 15.09.2011 / 21:57
fonte

Tags