25 coisas que nós amamos no Java
A JetBrains adora todas as linguagens de programação e desenvolvedores de todos os tipos! Este mês, maio de 2020, o Java completa 25 anos! Portanto, queremos prestar uma atenção especial e comemorar 25 coisas que adoramos no Java e na JVM.
Compatibilidade com versões anteriores
O Java é quase único em sua capacidade de executar código de 25 anos atrás em uma versão moderna do Java. Os desenvolvedores de linguagens levam a compatibilidade com versões anteriores muito a sério e, por causa disso, muitas organizações estão muito satisfeitas por fazer do Java sua plataforma de desenvolvimento principal, sabendo que o código ainda será executado na JVM nos próximos anos.
Maturidade
Há muitas vantagens em estar presente por um longo tempo. Nos últimos 25 anos, os desenvolvedores têm criado aplicações em Java para uma grande variedade de setores e tipos de negócios e para diferentes plataformas. Enquanto isso, há 25 anos, os desenvolvedores aprendem Java em escolas, universidades, bootcamps e no trabalho. Isso cria um grande ecossistema que teve tempo de aprender com a experiência e que continua a crescer. O Java e os problemas que ele é capaz de resolver estão bem documentados e são bem suportados por fornecedores e organizações sem fins lucrativos e por indivíduos. Muito importante para desenvolvedores como nós, a maturidade e a ampla adoção do Java significam que há muitos trabalhos para desenvolvedores que desejam codificar em Java!
Melhorias constantes
Em contraste com a Compatibilidade com versões anteriores e a Maturidade, está a evolução da plataforma e da linguagem. Desde 2017 (Java 9), há um novo lançamento a cada seis meses, o que permite um fluxo constante de alterações e melhorias na linguagem. Combinada com os Recursos de Visualização, a linguagem é capaz de experimentar com uma nova sintaxe, obter feedback dos desenvolvedores e padronizar novos recursos que realmente funcionam bem para quem a usa.
Equilíbrio
O Java tem um equilíbrio difícil de encontrar entre a compatibilidade com versões anteriores e o futuro. A abordagem atual, que consiste em valorizar a compatibilidade com versões anteriores e lançamentos de uma nova versão a cada seis meses, mas com um lançamento de umaversão LTS (Suporte a longo prazo) a cada três anos parece atingir o equilíbrio certo. A linguagem é capaz de evoluir fornecendo avisos de recursos obsoletos que serão removidos e tendo substituições para qualquer coisa que possa desaparecer.
Aqueles que desejam estabilidade extra podem ficar com os lançamentos de Suporte a longo prazo. Para reduzir o risco quando chegar a hora de atualizar, eles podem testar regularmente as versões semestrais. Aqueles que estão contentes em atualizar a cada seis meses podem passar para a versão mais recente do Java sempre que esta for lançada. Os desenvolvedores que quiserem experimentar a nova sintaxe antes mesmo da padronização podem habilitar recursos de pré-visualização e, quem quiser fazer isso o mais rápido possível pode até mesmo usar o release de Acesso antecipado (Early Access) de uma versão que ainda não foi lançada. Equipes que usam versões modernas do Java realmente podem ter o melhor de todos os mundos.
Padrões
Padrões podem não ser tão empolgantes para um desenvolvedor quanto os recursos de linguagem, mas ter padrões para Java, Java EE e Jakarta EE e para casos de uso comuns com os quais os desenvolvedores se deparam facilita a vida de todos eles. Entender como usar o JDBC para conversar com um banco de dados significa que não precisamos nos preocupar em como o driver de banco de dados é implementado: a maneira como interagimos com ele é sempre a mesma. O JCP é um dos processos usados para determinar padrões para o Java.
A Especificação da linguagem Java (JLS) descreve os conceitos da linguagem Java e como o compilador deve funcionar. Ela inclui o Java Memory Model, que pode nos ajudar a prever como uma aplicação pode se comportar, independentemente da JVM ou do hardware. A documentação Java Virtual Machine Specification abrange os detalhes de baixo nível na JVM. Essas especificações permitem que os JDKs distribuídos por diferentes fornecedores, executados em plataformas diferentes, se comportem de maneiras previsíveis e especificadas. O que nos leva a…
Write Once Run Anywhere
A WORA foi uma das ideias originais por trás do Java, que parece tão óbvia hoje em dia que talvez nem percebamos o quanto ela foi revolucionária. Lembro-me de trabalhar para uma organização muito grande que, em 2002, mudou da pilha de tecnologia anterior para o Java simplesmente porque tinham vários componentes de hardware diferentes, e a capacidade de executar novos aplicações Java nesses componentes, em vez de precisar comprar hardware específicos para as aplicações, foi uma das principais razões pelas quais eles mudaram todo o seu desenvolvimento para o Java. Nos dias de hoje na nuvem, isso pode parecer menos relevante, mas na verdade, como nem sempre vemos a WORA em ação, não significa que ainda não estejamos nos aproveitando dela. E, é claro, se você estiver usando o IntelliJ IDEA (ou o NetBeans), estará aproveitando a WORA na área de trabalho.
Desempenho
Às vezes, isso vem como uma surpresa para aqueles que estão menos familiarizados com o Java, mas o Java é uma linguagem de alto desempenho. É uma plataforma madura que possui 25 anos de melhorias de desempenho; inúmeros recuperadores de memória (garbage collectors) com diferentes perfis de desempenho, e a JVM otimiza nosso código em tempo de execução para nossos casos de uso de produção reais de maneira muito melhor que a maioria dos desenvolvedores humanos. O Java é amplamente utilizado no mundo financeiro, por exemplo, que depende de transações de baixa latência e desempenho previsível.
Garbage Collection
A limpeza automática de memória (Garbage Collection) é outra coisa que, 25 anos depois, damos como certa. Não precisamos pensar em como a memória é alocada em nossas aplicações ou em como liberá-la. Cada JVM possui um ou mais algoritmos de GC diferentes e, portanto, podemos escolher um que funcione bem para nossa aplicação sem nos preocuparmos muito com o funcionamento interno e podemos continuar escrevendo a lógica de negócios das nossas aplicações.
Observabilidade e gerenciamento
Se estamos interessados no que está acontecendo enquanto nossa aplicação está em execução, há um grande número de ferramentas disponíveis para nós. Muitos delas são gratuitas, principalmente porque o Java Flight Recorder e o Mission Control agora fazem parte do OpenJDK (desde o Java 11). Ferramentas como o JMX inclusive nos permitem gerenciar dinamicamente nossas aplicações também.
A Máquina Virtual Java (JVM)
Muitos dos recursos que acabamos de mencionar são recursos da JVM, mas queremos especificamente realçar a JVM e o fato de ela ser separada da linguagem Java. Há muitas razões para adorar a JVM, incluindo algumas das coisas sobra as quais já falamos: WORA, otimizações de tempo de execução, desempenho, escolha de fornecedores etc., muitas das quais são possíveis devido a padrões e especificações. É importante que a JVM também seja separada da linguagem Java, pois significa que diferentes linguagens podem ser construídas na plataforma, aproveitando todos os ótimos recursos da JVM que acabamos de mencionar e, ao mesmo tempo, fornecendo diferentes tipos de sintaxe e recursos de linguagem.
Outras linguagens da JVM
Uma das razões pelas quais o Java sobreviveu, e até mesmo prosperou, naqueles anos tranquilos entre o Java 6 e 8 (o Java 7 tem ótimos recursos, mas não foi visto como um grande lançamento pelo desenvolvedores Java) é por causa das outras linguagens da JVM. Na JetBrains, é claro, nossa favorita é o Kotlin, mas a JVM é uma plataforma para outras linguagens populares, como Groovy, Scala, Clojure and JRuby e um grande número de outras linguagens novas e reimplementadas. Em muitos casos, a interoperabilidade entre essas linguagens e o Java clássico nos ajuda a abraçar e alavancar essa variedade.
Bibliotecas e frameworks
Um dos argumentos mais convincentes é a enorme quantidade de opções que temos de bibliotecas e frameworks, muitas delas open source e de uso gratuito. Frameworks populares como o Spring e o Spring Boot em particular, facilitam a criação de qualquer coisa, desde pequenos serviços até aplicações corporativas grandes e complexas. Padrões significam que geralmente não é difícil entender e usar uma biblioteca quando usamos algo semelhante em outro contexto. A maturidade do Java e a adoção antecipada do open source pela comunidade significa que geralmente há uma solução existente para problemas padrão, sem a necessidade de reinventar a roda. Isso também significa que, já que muitas dessas soluções existem e estão em uso há muito tempo, elas são bem testadas, bem compreendidas e bem documentadas.
Ferramentas de build e gerenciamento de dependências
Ficaram para trás os dias em que um pobre desenvolvedor (como eu!) tinha que procurar na Internet por um arquivo JAR desconhecido contendo alguma classe aparentemente exigida pelo código que ele estava tentando executar. O Maven e o Gradle, em particular, tornaram mais fácil não só gerar e implantar uma aplicação, como também configurar um projeto de maneira padrão com todas as dependências necessárias. É fácil começar a codificar em um projeto novo ou existente. Repositórios públicos como o Maven Central e o Bintray facilitam a localização (e publicação) de bibliotecas.
JUnit e testes automatizados
O JUnit foi criado em 1997 e, portanto, é quase tão antigo quanto o próprio Java! Ele é de longe o framework de teste automatizado mais comum no mundo Java, e o JUnit e o TestNG acompanham o IntelliJ IDEA, pois considera-se que um framework de teste será necessário com qualquer novo projeto Java. É provável que as estruturas de teste modernas para uma variedade de linguagens sejam baseadas nas ideias que agora aceitamos como certas da JUnit. A cultura da comunidade Java de testes automatizados deve muito a essa biblioteca.
IDEs
Este é o blog do IntelliJ IDEA, não tem como esquecer! Se você acredita que a verbosidade do Java requer um IDE ou que, na verdade, o Java pode realmente alavancar um IDE devido à sua tipagem estática, o fato é que os desenvolvedores Java adoram seus IDEs (e nós amamos vocês!). Aprender a usar um IDE de maneira eficaz (seja o IntelliJ IDEA, o Eclipse ou o NetBeans) pode melhorar significativamente a produtividade de um desenvolvedor, por meio do seguinte: complementação e geração de código, execução de testes, depuração, navegação e vários outros recursos. Os desenvolvedores Java geralmente são extremamente entusiasmados com os benefícios que um IDE é capaz de trazer.
Comunidade
A Comunidade Java é uma grande, madura, vibrante e acolhedora. Existem Grupos de usuários Java em muitas cidades do mundo e um Grupo virtual de usuários Java se você não puder ir a um meetup presencial. Os Java Champions são líderes técnicos reconhecidos no mundo Java que se tornaram conhecidos por compartilhar coisas úteis ou interessantes para desenvolvedores Java e JVM. O Java possui uma enorme comunidade open source, incluindo o próprio JDK, por meio do OpenJDK. A Comunidade Java valoriza o aprendizado, o ensino e o aprimoramento constante, se preocupa com os padrões e as “melhores práticas” e é pragmática sobre como aplicá-los em um ambiente do mundo real.
Pessoas
A Comunidade é composta de pessoas, é claro, mas quando perguntei o que os desenvolvedores mais valorizam sobre o Java, muitos deles especificamente mencionaram pessoas no mundo do Java que os influenciaram. Elas variam desde colegas e professores a pessoas como Brian Goetz, Angie Jones, Georges Saab, Mala Gupta e Venkat Subramaniam. Algumas pessoas até mencionaram meu nome. Pessoalmente, escolhi o Java porque aprendi na universidade e havia muitos empregos naquela época, mas continuei com ele porque amo as pessoas, a ajuda e o apoio que tive delas.
Javadoc e Documentação
O Java faz da documentação da API uma parte essencial da linguagem por meio do Javadoc. Os três tipos diferentes de comentários (Javadoc, bloco e linha) indicam claramente que tipo de comentário um desenvolvedor está deixando. O Javadoc especificamente encoraja os desenvolvedores a deixar a documentação útil para outros desenvolvedores que chamam um método ou usam uma classe ou um pacote. Se um desenvolvedor não consegue encontrar informações detalhadas do tutorial em uma biblioteca ou parte de código, geralmente há um Javadoc que pode ajudar a apontá-los na direção certa.
Além disso, o ecossistema Java geralmente parece esperar (e fornecer) documentação de boa qualidade para os desenvolvedores. Os potenciais participantes de projetos open source são encorajados a enviar solicitações de extração de comentários do Javadoc ou outra documentação, e os desenvolvedores em todo o mundo fazem e respondem perguntas no StackOverflow ou publicam em blogs sobre soluções para problemas específicos.
Open source
A comunidade Java não apenas adotou o open source desde o início, como também agora o JDK é open source por meio do OpenJDK. O open source facilita a participação e a colaboração de vários fornecedores, bem como de indivíduos. Também é fascinante poder ver o código do próprio Java. O código open source oferece uma grande oportunidade para desenvolvedores como nós aprendermos com pessoas que já fizeram todo o trabalho duro pensando e resolvendo problemas complicados.
Grátis
A plataforma Java e muitas das ferramentas mais populares usadas no ecossistema Java não exigem que um desenvolvedor (ou mesmo uma organização com fins lucrativos) pague para usá-las. Mesmo depois que a Oracle alterou seu licenciamento e suporte no Java 11, ela (e muitos outros fornecedores) ainda forneceram uma maneira de usar a linguagem gratuitamente em produção. Os projetos open source, as ferramentas de compilação e os IDEs já mencionados neste artigo são gratuitos ou têm uma opção gratuita. Isso torna o Java atraente para os desenvolvedores que estão começando a codificar e para organizações de todos os portes que precisam criar softwares e manter um olho no orçamento.
Orientado a objetos (OO)
A Programação orientada a objetos não é a única opção, claro, e todo paradigma tem suas vantagens e desvantagens. O Java foi projetado como uma linguagem OO desde o início, e muitos exemplos de padrões de design e outras práticas recomendadas de codificação para OO são demonstrados em Java. Se você deseja uma linguagem de programação Orientada a objetos, o Java deve estar no topo da sua lista de opções para experimentar.
Evolução e adaptação
O Java foi, e ainda é, uma linguagem de programação orientada a objetos. Porém, ele também adotou com sucesso alguns conceitos da programação funcional (como expressões lambda e estruturas de dados imutáveis) e os fez funcionar bem dentro do paradigma de OO. A inferência de tipo (por exemplo, var) nos permite ainda ter os benefícios de uma linguagem estaticamente tipada, mas com menos artifícios. A ciência da computação ainda é uma disciplina relativamente jovem, mas, à medida que aprendemos coisas novas, elas podem ser aplicadas às nossas ferramentas existentes. O Java (a linguagem e todo o ecossistema) está em constante evolução de acordo com as novas tendências e novas “melhores práticas” e também como resultado de ver como as coisas funcionam no mundo real.
O Java também se beneficia da sintaxe e das ideias de outras linguagens JVM, para ver o que funciona e o que talvez não se encaixe no mundo clássico do Java. Até mesmo os processos e as ferramentas que o Java usa para evoluir e crescer, como o JCP e OpenJDK, também estão se adaptando para permanecer relevantes nessa constante evolução. Essa evolução e adaptação fazem parte do equilíbrio cuidadoso que o Java deve atingir.
Foco na legibilidade
O código Java geralmente é legível, mesmo para programadores não Java. A linguagem tende a ser mais expressiva do que concisa demais, o que facilita a compreensão durante a leitura. Os desenvolvedores de linguagens não implementaram recursos como sobrecarga de operador, pois consideram importante não se surpreender com o comportamento personalizado inesperado. Há uma tendência a evitar “mágica” na linguagem e nos frameworks – embora alguns frameworks usem coisas como Convenção sobre configuração para fazer coisas sem que um desenvolvedor precise ser imperativo, definitivamente houve uma tendência de deixar de (por exemplo) fazer muito AOP com anotações e passar a usar anotações para verificações de documentação e análise estática. A comunidade e o ecossistema tendem a gostar de padrões e “melhores práticas”. Portanto, o código Java geralmente segue tipos semelhantes de regras, mesmo em projetos muito diferentes.
Recursos da linguagem
Falamos sobre 23 coisas que gostamos sobre o Java, mas não mencionamos um único recurso! Para ser honesto, é porque nos limitar a apenas 25 recursos parecia extremamente difícil e também porque muitas das coisas que adoramos no Java nem sempre são sobre a sintaxe ou os recursos. Gostaríamos de fazer uma homenagem a alguns recursos favoritos de acordo com os desenvolvedores:
-
API Collections: está conosco há muito tempo e nos serviu bem!
- Métodos convenientes de fábrica para coleções: facilitam muito a criação de coleções não modificáveis.
- API Streams: uma adição muito boa à API Collections e é ótimo vê-la evoluindo desde o Java 8. Fluxos paralelos adicionaram uma nova maneira de utilizar hardware moderno.
- Expressões Lambda: particularmente úteis com a API Streams, mas muito úteis por mérito próprio.
- Optional: uma boa maneira de expressar que um método pode não lhe dar algo (e nos impede de nos proteger contra NullPointerExceptions!). É muito bom ver cada melhoria em Optional desde o Java 8 também.
- java.time: a API mais recente para trabalhar com data e hora é uma melhoria bem-vinda
- Exceções verificadas: as revisões são divididas entre exceções verificadas e exceções para execução, mas as exceções marcadas existem pelo menos para as pessoas que desejam usá-las.
- Anotações: anotações são como (entre outras coisas) documentação que o compilador pode verificar ou notas para um framework para fazer algum trabalho pesado.
- JShell: agora, podemos jogar com o Java em um REPL
- var: a inferência de tipo ajuda a reduzir o ruído do código, se usada de forma sensata
- Modificadores de acesso e modularidade: o Java facilita (ainda mais desde o Java 9) ser explícito sobre qual código pode acessar quais campos, métodos, classes e módulos.
- Expressões Switch: agora, se usarmos Switch, é muito menos feio!
- NullPointerExceptions úteis: quem não adora uma boa NullPointerException? A mensagem de erro se tornou mais informativa e vemos exatamente onde ocorreu uma exceção na cadeia de chamadas.
- Recursos de demonstração: adoramos recursos de demonstração! Estamos muito empolgados com os Registros; Correspondência de padrões para instanceof e Blocos de texto.
O Futuro
Estamos recebendo novos recursos a cada seis meses, e cada uma das releases LTS geralmente oferecem melhor desempenho imediato para qualquer aplicativo em execução. O Java 15 (setembro de 2020) deve ter: Classes ocultas, Blocos de texto (não é mais preview); pré-visualizações atualizadas para Registros; Correspondência de padrões para instanceof e um preview de Classes seladas.
Além disso, esperamos também ver no futuro: concorrência leve e fácil de usar com Project Loom; Inline Types do Project Valhalla; mais alterações de linguagem do Project Amber, como sobras lambda; o Project Panama facilitará o acesso dos programadores a APIs estrangeiras, com tempos de inicialização mais curtos graças ao Project Leydon; mais melhorias para vários Garbage Collectors e muito mais.
O futuro é brilhante para o Java!