Este é um ótimo momento para postar isso, logo no lançamento do Java 19. Sim, outro post "minha linguagem é melhor". Não, eu não queria escrevê-lo. Mas às vezes a má projeção das pessoas leva a melhor sobre mim. Nesse caso, o post começou como um comentário e acabei decidindo transformá-lo em post. Isso foi reforçado com este post que reclama principalmente do Quarkus (um tanto injustamente, se devo acrescentar).
O primeiro artigo é principalmente clickbait sem sentido e desatualizado. Vou resumir para você nas seguintes afirmações:
[]
em coleções e +
em qualquer coisa
O segundo artigo tem reclamações mais relacionadas ao Jakarta EE e à estética geral do programador na JVM. Especificamente o uso de anotações para validações e reivindicações semelhantes. Este é um artigo muito mais bem informado, mas tem algumas falhas que abordarei no final.
Getters e setters não são necessários para o Java moderno. Temos registros desde o Java 14 e o Lombok ainda é bom, apesar de algumas afirmações em contrário. O único ponto em que precisaríamos de getter/setters é em configurações muito específicas (por exemplo, JPA), onde, novamente, o Lombok resolve o problema perfeitamente.
O artigo se baseia em um discurso sobre a falta de recursos de açúcar sintático em Java. Isso é intencional. Você pode consultar o Kotlin se estiver interessado nas nuances de sintaxe mais recentes. Java é sobre "lento e constante". Isso é bom e a principal razão por trás da longevidade do Java.
O Java moderno inclui padrões em switch, var, strings multilinha e muito mais. Alguns recursos futuros incluem modelos de string. O suporte ao modelo de string demora um pouco porque o Java quer "fazer certo". Há algum suporte para isso no nível da API (e já existe há algum tempo). Isso não é performático. O objetivo dos modelos de string é criar uma sintaxe substituível radical que permitiria coisas como:
ResultSet rs = DB."SELECT * FROM Person p WHERE p.last_name = \{name}";
Atualização: desde a publicação desta postagem, os desenvolvedores assumiram erroneamente que o código acima é uma vulnerabilidade de injeção de SQL. Não é. Isso parece uma substituição de string, mas é um código que usa essa sintaxe para gerar uma chamada SQL parametrizada.
Observe que name
é uma variável que o compilador verificará e obterá do escopo dinamicamente!
O DB
de dados pode ser implementado de forma personalizada pelo desenvolvedor e não precisa ser "incorporado" para que você possa construir modelos complexos no local.
Mas vamos falar sobre o Java que temos hoje, não o que vem daqui a 6 meses. Usar append não tem sido a recomendação para String
por uma década ou mais. Use +
que é o mais eficiente e fácil de ler. Sobre coleções, a diferença entre get()
e []
é literalmente quatro caracteres. Esses personagens importam muito. Podemos facilmente substituir isso. Também podemos entender as diferenças semânticas. As matrizes Java são MUITO rápidas, em muitos casos a velocidade nativa é rápida. As coletas não podem ser tão rápidas, o fato de podermos ver isso aqui instantaneamente é muito valioso.
O fato de que os operadores não podem ser sobrecarregados é um benefício ENORME. Se eu vir a + b
, sei que é uma string ou um número, não algum método oculto. Esse é um dos maiores pontos fortes do Java e uma das razões pelas quais ele é popular há quase 30 anos, enquanto outras linguagens são deixadas de lado. A sintaxe de Java é projetada para leitura em escala. Quando você tem um projeto com 1 milhão de linhas de código ou até 100 mil, os problemas mudam. Neste ponto, descobrir que o programador X no módulo Y cancelou um operador incorretamente quando você está depurando um problema é difícil. A sintaxe deve ser simples nesse ponto e qualquer custo menor que você economizou inicialmente será pago com juros de 10x. A definição de flips simples como código torna-se mais complexa e envelhece. Acrescente a isso o poder das ferramentas para analisar código simples e estrito em grande escala e isso se torna um benefício ainda maior.
As exceções verificadas são opcionais. Mas eles são um dos MELHORES recursos em Java. Tanto código falha inesperadamente. Quando você está construindo coisas como um hobby, pode ser OK. Quando você deseja criar um aplicativo profissional, precisa lidar com todos os erros. As exceções verificadas ajudam a evitar esse absurdo. As pessoas odeiam exceções verificadas por causa da preguiça. Java protege você contra você mesmo.
Não deve haver nenhum caso em que eu faça uma conexão de rede, uma conexão de banco de dados, abra um arquivo etc. e não precise lidar com o possível erro. Eu posso chutá-lo, mas as exceções verificadas me forçam a continuar chutando em algum lugar. É um recurso incrível.
Eu tenho muitos problemas com Maven e Gradle. Mas quando você o compara a praticamente qualquer outro sistema de dependência com alguma milhagem, eles estão indo muito bem. Eles têm problemas, mas você não pode compará-los com algo jovem como carga que quase não tem pacotes em comparação. A central do Maven é MASSIVA com 27 terabytes de jars e 496 bilhões de solicitações. Funciona perfeitamente e quase não tem tempo de inatividade.
Outras ferramentas como o NPM demonstram perfeitamente os pontos fortes do maven. Se as dependências no maven forem um problema, o NPM terá 100 vezes o problema e nenhuma supervisão. À medida que essas coisas crescem, há complexidades. Especialmente com várias versões do maven no mercado. No entanto, uma das coisas que o maven e o gradle têm a seu favor são as ferramentas. Em muitos casos, os IDEs ajudam a resolver problemas e encontrar a solução imediatamente.
O segundo artigo é mais interessante e até certo ponto eu concordo. Os desenvolvedores Java tendem a transformar cada problema em um problema mais complicado. Em alguns casos, isso é necessário, Java é o gorila de 800 libras das plataformas de programação e suas soluções geralmente são projetadas em excesso. Isso tende a ser melhor do que com pouca potência, mas tem um preço.
O artigo trouxe um exemplo interessante que parece ser a "coisa certa" para o observador casual, mas é problemático.
@NotNull @Email String noReplyEmailAddress
O autor afirma que isso é ruim e deve-se implementar digitação personalizada, por exemplo:
public record EmailAddress(String value) { public EmailAddress { // We could've used an Either data type, ofc; Objects.requireNonNull(value); // regexp could be better if (!value.matches("^[^@\\s]+@\\S+$")) throw new IllegalArgumentException( String.format("'%s' is not a valid email address", value)); } }
Isso é totalmente possível em Java, pois o código acima é um código Java válido. Mas tem vários problemas e é por isso que temos validação de bean.
Como resultado, as anotações podem parecer estranhas e não forçar a digitação. Isso é verdade. Mas eles aumentam o desempenho e a potência. Há muito pensamento e bom senso por trás de seu uso. Eu entendo o ponto dos autores, também não sou um grande fã de IoC, mas neste caso específico ele está incorreto.
Este artigo passou muito tempo na defensiva. É hora de mudar de marcha. O Java existe há quase 30 anos e ainda é compatível principalmente com o Java 1.0. Isso é fantástico e inigualável!
Um dos poderes de sua abordagem conservadora é que ele pode fazer incríveis otimizações "sob o capô" sem que nenhum de vocês perceba o que aconteceu. O Java 9 substituiu completamente a maneira como as strings eram representadas na memória de maneira transparente e reduziu significativamente o uso da RAM. Da mesma forma, o Loom aumentará a taxa de transferência de aplicativos síncronos Java. Valhalla irá melhorar ainda mais o desempenho da coleção e unificar a divisão Objeto/Primitivo. O Panamá finalmente nos livrará do JNI e tornará o processo de integração com o código nativo muito mais agradável.
O bom é que a JVM é uma grande tenda. Se você não é fã de Java, Kotlin ou Scala podem se adequar ao seu gosto. O benefício da JVM se aplica universalmente e a maioria dos recursos que mencionei aqui beneficiará todo o nosso ecossistema conjunto.
Esta história foi publicada pela primeira vez aqui.