Duvida sobre Generics

Como faço para criar um método com um parâmetro genérico? Preciso fazer um conversor de String para Enum porem esse conversor vai funcionar para uma serie de enums diferentes. Estava pensando em criar um metodo que receberia um Enum do tipo desejado para a conversão e a string a ser comparada no enum, como ficaria isso?

Vc pode aproveitar o type parameter da classe:

class Test<T> {
    void test(T param) { /* ... */ }
}

Ou definir o type parameter no próprio método, neste cado ele vem antes do tipo do retorno:

class Test {
    <T> void test(T param) { /* ... */ }
}

Para o que vc precisa, vc poderia usar a mesma assinatura do método Enum.valueOf, veja:

https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/Enum.html#valueOf(java.lang.Class,java.lang.String)

Na verdade pode ser que o próprio Enum.valueOf já faça o que vc quer, mas se não, vc faria algo assim:

public class Program {
  enum DiaDaSemana {
    SEGUNDA, TERCA, QUARTA, QUINTA, SEXTA, SABADO, DOMINDO
  }

  enum Vogal {
    A, E, I, O, U
  }

  enum Classe {
    MAGO, GUERREIRO, CLERIGO
  }

  public static <T extends Enum<T>> T converte(Class<T> enumClass, String name) {
    return Enum.valueOf(enumClass, name);
  }

  public static void main(String... args) throws Exception {
    System.out.println(Enum.valueOf(DiaDaSemana.class, "SEGUNDA"));

    System.out.println(converte(DiaDaSemana.class, "SEGUNDA"));

    System.out.println(converte(Vogal.class, "O"));

    System.out.println(converte(Classe.class, "GUERREIRO"));
  }
}
3 curtidas

Funcionou muito bem! Obrigado.

1 curtida

Boa noite, cara agora eu empaquei em outro lugar, eu tenho uma serie de enums para eu fazer essa conversão, e qual seria a melhor maneira de eu converter uma serie de valores com enums diferentes?

A melhor maneira não dá pra te dizer sem saber exatamente o que vc quer fazer, mas eu tenho algumas ideias de como poderia ser feito usando um Map.

import java.util.HashMap;
import java.util.Map;

public class Program {
  private static void experimento1() { // @formatter:off
    enum A { A1, A2 }
    enum B { B1, B2 }
    enum C { C1, C2 }

    Map<String, Enum<?>> map = new HashMap<>();

    map.put(A.A1.name(), A.A1);
    map.put(A.A2.name(), A.A2);
    map.put(B.B1.name(), B.B1);
    map.put(B.B2.name(), B.B2);
    map.put(C.C1.name(), C.C1);
    map.put(C.C2.name(), C.C2);
  }

  private static void experimento2() {
    interface MyEnum { }
    enum A implements MyEnum { A1, A2 }
    enum B implements MyEnum { B1, B2 }
    enum C implements MyEnum { C1, C2 }

    Map<String, MyEnum> map = new HashMap<>();

    map.put(A.A1.name(), A.A1);
    map.put(A.A2.name(), A.A2);
    map.put(B.B1.name(), B.B1);
    map.put(B.B2.name(), B.B2);
    map.put(C.C1.name(), C.C1);
    map.put(C.C2.name(), C.C2);
  }

  public static void main(String... args) {
    experimento1();
    experimento2();
  }
}

No experimento1 eu use Enum<?> e no experimento2 foi só pra mostrar que vc pode fazer seus enums implementarem sua própria interface.

Entendi, mas nesse caso eu teria de sempre chamar o enum e ja inicia-lo? O proposito desse projeto é pegar uma string que chega de um payload e transformar num enum caso bata com algum valor. A parte do parser está correta, mas como eu faria para pegar essa string e ver qual valor e o enum que bate?

Usando o exemplo anterior, vc faria algo assim:

import java.util.HashMap;
import java.util.Map;

public class Program {
  private static void experimento1() { // @formatter:off
    enum A { A1, A2 }
    enum B { B1, B2 }
    enum C { C1, C2 } // @formatter:on

    Map<String, Enum<?>> map = new HashMap<>();

    map.put(A.A1.name(), A.A1);
    map.put(A.A2.name(), A.A2);
    map.put(B.B1.name(), B.B1);
    map.put(B.B2.name(), B.B2);
    map.put(C.C1.name(), C.C1);
    map.put(C.C2.name(), C.C2);

    String payload = "A1";

    Enum<?> enumSelecionado = map.get(payload);

    if (enumSelecionado instanceof A) {
      switch ((A) enumSelecionado) {
      case A1:
        break;
      case A2:
        break;
      }
    } else if (enumSelecionado instanceof B) {
      switch ((B) enumSelecionado) {
      case B1:
        break;
      case B2:
        break;
      }
    } else if (enumSelecionado instanceof C) {
      switch ((C) enumSelecionado) {
      case C1:
        break;
      case C2:
        break;
      }
    }
  }

  public static void main(String... args) {
    experimento1();
  }
}

Mas não sei, parece errado de alguma forma. Eu só apresentei isso porque eu não sei o contexto todo, dependendo do que vc quer, com certeza há solução melhor.