Sobes.tech
Middle

Que funcionalidades oferecem os Genéricos em Java?

sobes.tech IA

Resposta da IA

Os genéricos em Java melhoram a segurança de tipos do código, prevenindo erros em tempo de execução relacionados com a conversão de tipos. As principais funcionalidades:

  • Verificação de tipos em tempo de compilação: O compilador verifica o uso correto dos tipos especificados nos genéricos, permitindo identificar erros antes de executar o programa.

    // Sem genéricos - possível ClassCastException
    List list = new ArrayList();
    list.add("string");
    list.add(123); // Adicionando um Integer
    String s = (String) list.get(1); // Erro em tempo de execução
    
    // Com genéricos - erro de compilação
    List<String> stringList = new ArrayList<>();
    stringList.add("string");
    // stringList.add(123); // Erro de compilação
    String str = stringList.get(0); // Obtenção segura
    
  • Eliminação de conversões de tipos (type casting): Os genéricos eliminam a necessidade de conversões explícitas ao obter elementos de coleções ou usar classes parametrizadas.

    // Sem genéricos
    List list = new ArrayList();
    list.add("Olá");
    String s = (String) list.get(0); // Conversão explícita
    
    // Com genéricos
    List<String> stringList = new ArrayList<>();
    stringList.add("Olá");
    String str = stringList.get(0); // Nenhuma conversão necessária
    
  • Implementação de código genérico (Métodos Genéricos, Classes Genéricas, Interfaces Genéricas): Permitem criar algoritmos e estruturas de dados genéricos que funcionam com diferentes tipos, sem duplicar código.

    // Método genérico para imprimir um array
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }
    
    // Classe genérica - par de valores
    class Pair<K, V> {
        private K key;
        private V value;
    
        public Pair(K key, V value) {
            this.key = key;
            this.value = value;
        }
    
        public K getKey() { return key; }
        public V getValue() { return value; }
    }
    
  • Suporte a Wildcards: Permitem definir restrições flexíveis nos tipos em tipos parametrizados.

    • ? (Wildcard não limitada): Qualquer tipo.
    • ? extends T (Wildcard com limite superior): O tipo deve ser T ou um subtipo de T.
    • ? super T (Wildcard com limite inferior): O tipo deve ser T ou um supertipo de T.
    // Método que aceita uma lista de qualquer tipo
    public static void processList(List<?> list) {
        // ...
    }
    
    // Método que aceita uma lista de números ou seus subtipos
    public static void processNumbers(List<? extends Number> list) {
        // ...
    }
    
    // Método que aceita uma lista de strings ou seus supertipos
    public static void addStrings(List<? super String> list) {
        list.add("nova string");
    }
    
  • Uso na estrutura de coleções: Todas as principais classes de coleções (List, Set, Map, etc.) são parametrizadas, o que torna o trabalho com coleções seguro em termos de tipos e conveniente.

Os genéricos são um elemento-chave do Java moderno, aumentando a confiabilidade e a legibilidade do código.