Я думаю, что первый ответ не указывает на реальное решение: вы ДОЛЖНЫ также передать экземпляр класса вместе с T, например, так:
public T decode(String json, Class<T> cls) {
Gson gson = new Gson();
return gson.fromJson(json, cls);
}
Это потому, что здесь T является типом VARIABLE, а не ссылкой на тип; и используется только компилятором для добавления неявных приведений и проверки совместимости типов. Но если вы пройдете реальный класс, его можно использовать; и компилятор проверит совместимость типов, чтобы уменьшить вероятность несоответствия.
В качестве альтернативы вы можете взять TypeToken и передать его; но TypeToken должен быть создан с реальным типом, а не с переменной типа; Переменная типа здесь малопригодна. Но если вы хотите обернуть вещи, вы не хотите, чтобы вызывающая сторона использовала TypeToken (это тип Gson).
Тот же механизм обертывания будет работать с другими библиотеками, такими как Джексон, о котором вы упомянули.