DEV Community

Cover image for Evolução da linguagem Java (parte 1)
Paulo Porto
Paulo Porto

Posted on • Edited on

Evolução da linguagem Java (parte 1)

Você já pensou como a linguagem Java evoluiu nos últimos anos?

Neste artigo vamos relembrar os principais recursos que o Java trouxe ao longo das versões para tornar a vida do desenvolvedor mais fácil, permitindo escrever código mais limpo, conciso e simples.

Para começar, o primeiro grande salto! Do Java 4 para Java 5/6

Há muito tempo tive a oportunidade de trabalhar em um projeto com java 4 em um mundo que o java 5/6 já eram presentes.
Nesse tempo distante não existia a conversão automática de tipos primitivos para seu par em forma de objeto.

List lista = new ArrayList();

// Adicionar número: precisa criar explicitamente o objeto
lista.add(new Integer(10));
lista.add(new Integer(20));

// Recuperar número: precisa fazer cast + chamar intValue()
Integer obj = (Integer) lista.get(0);
int valor = obj.intValue();
Enter fullscreen mode Exit fullscreen mode

A partir do Java 5 nossa vida de desenvolvedor melhorou muito com Autoboxing/Unboxing e Generics.

List<Integer> nums = new ArrayList<Integer>();
nums.add(10);        // autoboxing
int x = nums.get(0); // unboxing
Enter fullscreen mode Exit fullscreen mode

Generics ajuda a eliminar casts manuais e tornara o código mais seguro.

Além disso tivemos a introdução de Enum, Varargs, Annotations, for-each e Static import.

na categoria qualidade de código, para mim a feature mais marcante do Java 6 foi o "Pluggable Annotation Processing Tool(APT)". Ela abriu caminho para frameworks como Lombok e JPA criarem código automaticamente.

Esquecido mas não menos importante, Java 7

Nós ganhamos o "Diamond Operator (<>)", "Multi-catch" e "Try-with-resources (ARM – Automatic Resource Management)".

Diamond Operator (<>) nos permite evitar a repetição de generics na criação de objetos.

// Antes
Map<String, List<Integer>> mapa = new HashMap<String, List<Integer>>();

// Java 7
Map<String, List<Integer>> mapa = new HashMap<>();
Enter fullscreen mode Exit fullscreen mode

Multi-catch permite tratar múltiplas exceções diferentes em um único bloco.

try {
    metodoArriscado();
} catch (IOException | SQLException e) {
    e.printStackTrace();
}
Enter fullscreen mode Exit fullscreen mode

Try-with-resources ajuda no fechamento automático de recursos que implementam AutoCloseable. (Quem nunca esqueceu de fechar um arquivo?)

// Antes
BufferedReader br = null;
try {
    br = new BufferedReader(new FileReader("dados.txt"));
    System.out.println(br.readLine());
} finally {
    if (br != null) br.close();
}

// Java 7
try (BufferedReader br = new BufferedReader(new FileReader("dados.txt"))) {
    System.out.println(br.readLine());
} // fecha sozinho
Enter fullscreen mode Exit fullscreen mode

O Java 7 trouxe também Strings no switch (finalmente!).

Vamos falar do segundo grande salto! Java 8

Neste salto, para mim os maiores destaques vão para "Lambda", "Streams API", "Optional" e "java.time".
Também tivemos os Default Methods em Interfaces — um recurso útil para evoluir APIs sem quebrar compatibilidade, embora seu uso ainda gere discussões entre desenvolvedores.

Podemos começar com "java.time".
Inspirada no Joda-Time. Surgiu para resolver o problema histórico das classes antigas de data e hora.

É sério! Já tentou somar X dias em um Date?

import java.util.Calendar;
import java.util.Date;

public class ExemploAntesJava8 {
    public static void main(String[] args) {
        // Data atual
        Date hoje = new Date();
        System.out.println("Hoje: " + hoje);

        // Usando Calendar para somar 18 dias
        Calendar cal = Calendar.getInstance();
        cal.setTime(hoje);
        cal.add(Calendar.DAY_OF_MONTH, 18);

        Date daqui18dias = cal.getTime();
        System.out.println("Daqui a 18 dias: " + daqui18dias);
    }
}
Enter fullscreen mode Exit fullscreen mode

Sempre que eu usava o Calendar precisava lembrar que os meses eram de 0 a 11 e não de 1 a 12.

import java.util.Calendar;
import java.util.Date;

public class ExemploAntesJava8 {
    public static void main(String[] args) {
        // Olha a pegadinha!
        Calendar cal2 = Calendar.getInstance();
        cal2.set(2025, Calendar.SEPTEMBER, 19); // Setembro = 8
    }
}
Enter fullscreen mode Exit fullscreen mode

java.time trouxe um modelo moderno, imutável e muito mais claro com classes imutáveis e thread-safe.

import java.time.LocalDate;

public class ExemploComJavaTime {
    public static void main(String[] args) {
        // Data atual
        LocalDate hoje = LocalDate.now();
        System.out.println("Hoje: " + hoje);

        // Somando 18 dias
        LocalDate daqui18dias = hoje.plusDays(18);
        System.out.println("Daqui a 18 dias: " + daqui18dias);
    }
}
Enter fullscreen mode Exit fullscreen mode

Streams API, mudou a forma de como fazemos loops no Java.

// Antes
List<String> nomes = Arrays.asList("Ana", "Bruno", "Alberto", "Carla");
int cont = 0;
for (String n : nomes) {
    if (n.startsWith("A")) cont++;
}

// Java 8
long cont = nomes.stream()
                 .filter(n -> n.startsWith("A"))
                 .count();
Enter fullscreen mode Exit fullscreen mode

Optional chegou para lidar de forma segura com valores que podem estar ausentes.

// Antes (null check em cascata)
String cidade = null;
if (usuario != null && usuario.getEndereco() != null) {
    cidade = usuario.getEndereco().getCidade();
}

// Java 8 (Optional)
String cidade = Optional.ofNullable(usuario)
                        .map(Usuario::getEndereco)
                        .map(Endereco::getCidade)
                        .orElse("DESCONHECIDA");
Enter fullscreen mode Exit fullscreen mode

Quem nunca retornou um Optional em um query method do Spring Data Jpa? Se não deveria tentar.

Para finalizar, Lambda!
No passado, sem os lambdas precisávamos de classes anônimas para implementar comportamentos simples.

List<String> nomes = Arrays.asList("Carlos", "Ana", "Bruno");

// Antes
Collections.sort(nomes, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});

// Usando Java 8 (lambda)
List<String> nomes = Arrays.asList("Carlos", "Ana", "Bruno");

nomes.sort((a, b) -> a.compareTo(b));
// Ou ainda mais curto com method reference
nomes.sort(String::compareTo);
Enter fullscreen mode Exit fullscreen mode

Veja a parte dois aqui.

Top comments (0)