Przkeazanie generycznego typu do metody generycznej

0

Czy da się jakoś przekazać typ generyczny do metody generycznej. Np.

public  <T> List<T> metoda(ComplexObject data){
    return new ObjectMapper().readValue(veryComplexLogicHere(data.getContext()), new TypeReference<List<T>>(){});
}

wywołanie takiej metody np. tak List<UserDto> users = metoda(complexObject); nie działa tak jakbym oczekiwał bo jackson nie jest w stanie przeprocesować danych na pożądaną listę obiektów UserDto. Zamiast tych obiektów dostaję LinkedHashMap co nie jest ok.

6
tdk1982 napisał(a):

Czy da się jakoś przekazać typ generyczny do metody generycznej. Np.

public  <T> List<T> metoda(ComplexObject data){
    return new ObjectMapper().readValue(veryComplexLogicHere(data.getContext()), new TypeReference<List<T>>(){});
}

wywołanie takiej metody np. tak List<UserDto> users = metoda(complexObject); nie działa tak jakbym oczekiwał bo jackson nie jest w stanie przeprocesować danych na pożądaną listę obiektów UserDto. Zamiast tych obiektów dostaję LinkedHashMap co nie jest ok.

W javie nie da się odczytać typów generycznych podczas działania aplikacji, musisz przekazać UserDto.class.

1

Dobrze, to się nie da. Typ generyczny nie istnieje w runtime, to jest jedynie dodatkowy constraint dla kompilatora.

Można zrobić brzydko:

public  <T> List<T> metoda(ComplexObject data, Class<T> clazz){
    ...
}

Wymusza to dopisanie tego parametru, ale jest bezpieczne, a rozwlekłość Javy jest podobno jej zaletą :)

Można też refleksją odczytać typ generyczny metody, ale to trochę chore i wysypie się, jak ktoś tam jakiegoś ? extends Something wrzuci.

@Riddle: wrzucę tutaj, bo w komentarzu ciężko się zmieścić:

public class Main {
    public List<String> listField = new ArrayList<>();
    public static void main(String[] args) throws NoSuchFieldException {
        Field listField = Main.class.getField("listField");
        System.out.println(listField.getGenericType().getTypeName());

    }
}

I output:
java.util.List<java.lang.String>

chyba, że chcesz wyciągnąć typ generyczny z obiektu: public List list = new ArrayList<String>();
To faktycznie, takie linijki:

        Main main = new Main();
        Method get = main.list.getClass().getMethod("get", int.class);
        System.out.println(get.getGenericReturnType().getTypeName());

Zwracają wiele mówiące E, zakładam, że tak ktoś zdefiniował typ Elementu listy.

0
piotrpo napisał(a):

@Riddle: wrzucę tutaj, bo w komentarzu ciężko się zmieścić:

public class Main {
    public List<String> listField = new ArrayList<>();
    public static void main(String[] args) throws NoSuchFieldException {
        Field listField = Main.class.getField("listField");
        System.out.println(listField.getGenericType().getTypeName());
    }
}

Noo, tylko że takim czymś nie odczytasz żadnych dodatkowych informacji których byś nie miał bez tego.

1 użytkowników online, w tym zalogowanych: 0, gości: 1