Executando verificação de segurança...
26

Você tá escrevendo Java errado

Toda semana é a mesma resenha, aparece um dev, direto de um código que parece ter saído de um museu, pra soltar a clássica: "Java é muito verboso". Aí chove post, comentário em pull request, e vira até desculpa pra justificar aquele método com mais linhas que a Bíblia.

Mas a real, é que quando a gente para pra olhar o código, a culpa não é bem do Java. É do nosso jeito de escrever.

Um disclaimer antes de começar: Sei que a realidade de muito dev por aí é trampar com código legado, onde nem sempre dá pra usar as features mais recentes. Às vezes, a gente é até obrigado a manter uns padrões mais antigos por causa do projeto. Meu objetivo aqui não é criticar quem tá nesse corre, muito pelo contrário! A resenha aqui é pra quem já tem a chance de usar as versões novas do Java, mas continua com a mentalidade e os hábitos lá de trás. Fechou? Então bora!

O verdadeiro problema? A preguiça de atualizar

Esse é o tipo de código que a galera faz e depois sai culpando a linguagem:

Pedido pedido = new Pedido();
pedido.setClienteId("cliente-957");
pedido.setValorTotal(189.50);
pedido.setItens(List.of("Moqueca de Camarão", "Acarajé", "Cerveja Gelada"));
pedido.setPago(true);
repository.salvar(pedido);

Seis linhas pra criar UM pedido?

Aqui em baixo, a mesma coisa, escrita por alguém que leu alguma release note desde 2015:

var pedido = new Pedido("cliente-957", 189.50, List.of("Moqueca de Camarão", "Acarajé", "Cerveja Gelada"), true);
repository.salvar(pedido);

Ou, se você nem vai usar a variável depois, pra que gastar linha à toa?

repository.salvar(new Pedido("cliente-957", 189.50, List.of("Moqueca de Camarão", "Acarajé", "Cerveja Gelada"), true));

Uma linha. Resolvido. A gente se dá o trabalho de escrever seis linhas pra fazer o que uma só resolveria... Assim fica difícil defender a firma, né?

Ainda na máquina de escrever: Getters e Setters em 2025

Vamos trocar uma ideia sobre de onde vem essa tal "verbosidade". Spoiler: tá mais perto do que a gente imagina.

Se em pleno 2025 a gente ainda tá digitando getX() e setX() na mão, parece que a gente virou uma impressora de código. Os Records tão ai desde o Java 14, prontos pra jogo.

public record Pedido(String clienteId, double valorTotal, List<String> itens, boolean pago) {}

É só isso. A classe inteira. Já vem com construtor, getters, equals(), hashCode() e toString() no pacote. Mas se você curte digitar 50 linhas a mais, quem sou eu pra julgar?

Aquele medo do var porque "é confuso"

Confuso, sério? Confuso mesmo é se deparar com isso aqui:

Map<String, List<PedidoDetalhado>> pedidosAgrupadosPorRegiao = relatorioService.agruparPedidosPorRegiaoDoPais();

Quando a gente podia ter a paz de um:

var pedidosAgrupadosPorRegiao = relatorioService.agruparPedidosPorRegiaoDoPais();

O tipo da variável tá na cara, ali no nome do método. Se tirar a declaração explícita deixa o código "ilegível", talvez o problema não seja o var, e sim o nome do método, que não tá contando a história direito.

A coleção de patterns pra resolver coisinha simples

Quem nunca viu? UserFactory, UserBuilder, UserManager, UserService, UserHelper, UserUtil. Uma constelação de classes pra fazer o que um construtor e dois métodos dariam conta.

Design patterns são ferramentas poderosas pra resolver problemas complexos, e não pra enfeitar o currículo. Criar um Factory pra um objeto de 3 campos é tipo usar um canhão pra matar uma formiga.

Deixando as novidades da linguagem no vácuo

O Java se reinventou, e muito! Mas tem muito código por aí que parece ter parado em 2005. Se liga no que já tá rolando:

  • Switch expressions (Java 14): Um jeito muito mais elegante de lidar com múltiplas condições.

  • Text blocks (Java 15): Pra escrever JSON ou SQL no código sem aquele malabarismo com +.

  • Pattern matching para instanceof (Java 16): Chega de fazer cast depois de verificar o tipo.

  • Sealed classes (Java 17): Pra ter controle de quem pode herdar suas classes.

  • Record patterns (Java 21): Pra desestruturar objetos de um jeito super simples.

Isso tudo já tá aí, pronto pra usar e deixar nosso código bem mais enxuto. Vale a pena dar uma olhada nos changelogs!

O Java moderno tá o puro suco

Vamos ser sinceros: do Java 14 pra cá, a linguagem é outra parada:

// Records para representar dados, simples e direto
public record PassagemAerea(String origem, String destino, double preco) {}

// Switch inteligente para tratar diferentes tipos de notificação
String processarNotificacao(Object notificacao) {
    return switch (notificacao) {
        case Email(var dest, var ass) -> "Enviando email para " + dest + " sobre: " + ass;
        case SMS(var num, var msg) -> "Enviando SMS para " + num;
        case String s -> "Notificação de sistema: " + s;
        case null, default -> "Tipo de notificação desconhecida";
    };
}

// Text blocks para montar um JSON de um evento local
var payloadEvento = """
    {
        "nome": "Festa de São João",
        "local": "Pelourinho, Salvador",
        "data": "2025-06-23",
        "atracoes": [
            "Forró do Tico",
            "Adelmário Coelho"
        ]
    }
    """;

// Streams para filtrar pedidos valiosos e já pagos
var pedidosValiosos = pedidos.stream()
                             .filter(p -> p.valorTotal() > 500.00 && p.pago())
                             .toList();

É verboso? Não. É claro? Sim. É moderno? Com certeza. A linguagem tá voando.

A verdade: a gente que complica

A real é que, na maioria das vezes, a "verbosidade" não é culpa do Java, mas sim de alguns hábitos que a gente pega:

  • A gente aprendeu Java lá em 2010 e esqueceu de ver as atualizações.

  • A gente repete uns padrões antigos do Spring como se fosse um mantra.

  • Às vezes a gente acha que código "enterprise" precisa ser complicado.

  • A gente nem sabia que o Java tinha ganhado tantos superpoderes.

  • Dá uma preguiça de refatorar, mas pra reclamar a gente tá sempre pronto.

A linguagem nos deu ferramentas incríveis. Só falta a gente começar a usar.

"Mas em outra linguagem é mais fácil!"

Ah, o clássico papo da grama do vizinho...

Sim, em Python você não precisa declarar o tipo. É legal, até o dia que sobe um bug pra produção porque você passou um texto onde era pra ser um número.

JavaScript? É conciso, sim. Mas também é aquele universo paralelo onde typeof null é "object" e "2" + 2"22".

Go é minimalista de propósito, o que é ótimo... até você sentir falta de umas coisinhas básicas que eles levaram uma década pra adicionar.

Toda linguagem é uma escolha, com seus prós e contras. Java apostou na segurança, estabilidade e em deixar as coisas bem claras. Se isso soa como "verboso", talvez a gente só não curta muito a filosofia da linguagem, e tá tudo bem.

O fantasma do AbstractSingletonProxyFactoryBean

Aquele nome gigante do Spring que todo mundo usa pra zoar o Java? Sim, ele existe. Não, você não escreve aquilo. É coisa interna do framework, láaaaaaa das profundezas.

Culpar o Java por isso é o mesmo que culpar o português pelo "juridiquês" dos advogados. Hoje em dia, com Spring Boot, a gente escreve um código limpo e direto ao ponto que nem esse:

@RestController
@RequestMapping("/pedidos")
public class PedidoController {
    private final PedidoRepository pedidoRepository;

    public PedidoController(PedidoRepository pedidoRepository) {
        this.pedidoRepository = pedidoRepository;
    }

    @GetMapping("/{id}")
    public Pedido getPedido(@PathVariable Long id) {
        return pedidoRepository.findById(id)
                .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Pedido não encontrado"));
    }
}

Cadê a complicação? Cadê os XMLs? Pois é, ficaram lá em 2008.

Aqueles null checks de museu...

E pra fechar, vamos falar dessa relíquia da programação defensiva:

public String getCodigoDeRastreio(Pedido pedido) {
    if (pedido != null) {
        if (pedido.getCodigoDeRastreio() != null) {
            return pedido.getCodigoDeRastreio();
        }
    }
    return "Não disponível";
}

Hoje em dia, a gente resolve isso com muito mais simplicidade:

public String getCodigoDeRastreio(Pedido pedido) {
    return Optional.ofNullable(pedido)
                   .map(Pedido::getCodigoDeRastreio)
                   .orElse("Não disponível");
}

A ideia aqui não é apontar o dedo pra ninguém, muito pelo contrário. A real é que o Java evoluiu DEMAIS, e às vezes, na correria, a gente fica preso no jeito antigo de fazer as coisas.

Se a gente se der a chance de explorar as features mais novas, vai descobrir um mundo de possibilidades pra escrever um código mais limpo, mais rápido e, por que não, mais divertido.

Carregando publicação patrocinada...
3

Acho que a unica coisa que eu não concordo e acho que nunca vou conseguir concordar é o var. Eu uso C++ no trabalho e a porcaria do auto é uma maldição que deveria ser banida.

Eu vejo que uma das coisas mais importantes de uma linguagem é você saber o que você tá mexendo. Quais são os métodos dessa variável e por ai vai.

Mas de resto, quando eu comecei a programar, tudo isso era de fato um problema. A linguagem evoluiu e tá um absurdo de bom.

Sobre o problema de atualização, eu conheço diversas empresas que o real problema não seria a preguiça, mas sim a falta da percepção de valor nessa tarefa.

Pouquíssimas vezes os desenvolvedores, líderes técnicos e até mesmo o CTO, conseguem mostrar essa percepção de valor e até mesmo tomar essa decisão. O lado do "business" não percebe que a tecnologia também possui a sua "obsolescência".

Mas, por outro lado, eu entendo que time que tá ganhando não se mexe.

Mas se for algo novo vale muito mais a pena usar as versões mais atyalizadas.

2

Que post incrível, meu caro.

Mesmo o Java sendo a minha principal linguagem de programação, muitas dessas features passaram despercebidas por mim durante os meus estudos, e isso é um problema: focar demais no "conceito" ou na resolução bruta do problema, ignorando todas as ferramentas que a linguagem oferece para facilitar a vida do desenvolvedor. Lembro-me bem do dia que o IntelliJ sugeriu o uso enhanced switch e achei aquilo o máximo, porém nunca mais utilizei essa funcionalidade.

Seu post é um compilado de funcionalidades incríveis e eu acho que todos os programadores que reclamam da verbosidade do Java deveriam experimentar esses recursos. Para mim, o grande trunfo do Java é justamente ser explícito, "na linha 15 vai acontecer isso por causa disso, disso e daquilo", sem mistérios, sem abstrações, sem suposições.

1

E notório seu profundo conhecimento das atualizações da linguagem, seria uma contribuição inestimável criar pequenos vídeo explicando as mudanças e como usar, para os novos devs.

1
1

Que comentário sensacional, Você resumiu perfeitamente um sentimento que muitos de nós temos. É exatamente isso, na correria pra entregar, a gente foca no "o quê" e esquece de olhar as ferramentas incríveis que o "como" nos oferece.

Muito obrigado por compartilhar sua visão, enriqueceu demais a discussão!

1

Muito bom, programo em Java faz muito tempo, e realmente, esquecemos de nos atualizar com as novidades.
Quando olhamos as formas mais simples de outras linguagens, ficamos impressionados, e esquecemos de checar tais funcionalidades no nosso velho e querido Java.

1

Você pegou o espírito da coisa. É fácil se impressionar com o que é novo em outras linguagens e esquecer que a nossa também não parou no tempo.

1

Olha, me parece que vc gosta mais do js do que do java, pq em quase todos os pontos vc quis copiar coisas do js;

Minha opinião pessoal:

  1. Construtor com mais de 5 parâmetros já vira uma bagunça;
  2. Optional é uma droga, ninguém me convence que aquilo ali é melhor do que um (!= null);
  3. O "var" é uma aberração e nunca deveria ter virado recurso;
  4. Sobre os "AbstractSingletonProxyFactoryBean", a gente sabe exatamente o que a classe faz pelo próprio nome;
  5. Sobre verbosidade, eu diria que cada linha faz sentido de estar ali, sem coisas mágicas acontecendo;
  6. Sobre o Records, achei legal a idéia mas não gostei da forma que foi implementado;
  7. Existe sempre um tradeoff, javascript é simples, mas é a casa da mãe joana, linguagens tipadas e verbosas são mais burocráticas, mas impedem muitos problemas by design;
0

SIM. Criei conta neste site graças ao post. Ia mencionar exatamente os pontos 3, 5 e 6.

Não gosto de usar var pois atrapalha a manutenção do código. Levar alguns segundos pra identificar o retorno de cada variável em um projeto médio/grande, no meu ponto de vista, é prejudicial. Esse ganho é crucial pra obter produtividade (fazer mais em menos tempo). O dev que for manutenir o seu código lhe agradecerá por isso.

Além do mais senti falta de uma menção honrosa ao Lombok. Opção de otimizar a quantidade de linhas da classe muito mais viável que Records que limitam o construtor, por exemplo. Em projetos médios já se percebe esse gargalo.

1

Eu nao uso lombock pq nao gosto de coisas magicas-auto-geradas, meio que briguei com meu toke eauheuh;
Meio que uma filosofia de que: "o que nao esta escrito, nao existe"

1

Eu não vejo problema no var se o mesmo for escrito da forma correta, por assim dizer, como no exemplo abaixo:
var usuario = usuarioService.findByLogin(login);

Com isso é fácil de olhar o código e entender o que a variável é.

1

Adorei seu post!

E sem contar que o Java 25 tá lindo demais, mano. Import modules, flexible constructor bodies, unnamed variables and parameters (podemos usar _ nos nomes das variáveis locais, parâmetros de metodos funcionais, parâmetro de exceção no bloco try-catch e etc, caso nao precisemos usar aquele parâmetro - so acho que poderiam ter colocado parâmetros sem nome igual o do C++, mas tudo bem, a linguagem vai se aprimorando com o tempo, né?), classfile API, primitive types in patterns and switches, structure concurrency, scoped values, vector api, FFM (Foreign Function Memory - substitui a sun.misc.Unsafe), key derivation function API, PEM encoding of crypto objects... Enfim, tá muito bacana ❤️

Até o java 24, construí um framework de mapeamento relacional de arquivos de propriedades em arquivos de classe Java usando a nova API ClassFile, pra manipular o bytecode java. Infelizmente tive que usar uma API externa pra manipular AST (JavaParser). Não sou muito fã de sobrecarregar meus projetos com APIs e frameworks de terceiros. Geralmente gosto de fazer tudo sozinho, até pra ir aprendendo mais sobre os internos do Java, sabe? Mas tá bem legal o projeto ❤️. Me inspirei no recurso de referência estática que o android studio usa pra referenciar valores de strings e outros valores dentro dos XMLs do diretorio res.
No Android Studio você chama R.strings.nome_da_string (faz tempo que não mexo com a IDE, então eu meio que esqueci essa parte). Meu framework você chama P.NomeDoArquivoDePropriedades.CHAVE_DA_PROPRIEDADE, sendo P em alusão a Properties, NomeDoArquivoDePropriedades seria a classe interna estática criada usando o nome do arquivo formatado e CHAVE_DA_PROPRIEDADE, que contém o valor mapeado.
Contém alguns bugzinhos ainda, mas com o tempo vou lançando novas releases. Agora tô fazendo um hot reloader aprimorado rpo JavaFX. Ele vai contar não somente com o hot reloader, mas também vai tentar mapear as mecânicas do app do dev pra poder fornecer um hot reloader funcional em runtime, apenas fazendo malabarismos com ClassLoaders kkkk

1
0
0
0
0