Общая десериализация

1

Я пытаюсь заменить какой-то старый код более общим подходом, поэтому я попытался использовать generics. К сожалению, до сих пор я не работал. Я должен динамически загружать хэш-карту объектов из строки json. Но до сих пор я не работал, поскольку строка 4

HashMap<String,c> hm = new HashMap<String,c>();

говорит "Неизвестный класс c". Что я делаю не так?

 public static HashMap<String,?> getEntries(Context context, Type t)
        {
            Class c = t.getClass();
            HashMap<String,c> hm = new HashMap<String,c>();
            try
            {
                File fl = new File(context.getCacheDir(),c.getClass().toString() + ".json");
                FileInputStream fin = new FileInputStream(fl);

                BufferedReader reader = new BufferedReader(new InputStreamReader(fin));
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append("\n");
                }
                fin.close();

                hm = new Gson().fromJson(sb.toString(), t);

            }catch(Exception i)
            {
            }
            return hm;
        }
  • 4
    Это не будет делать то, что вы ожидаете. Аргумент типа должен быть именем типа. c является переменной.
  • 2
    c.getClass().toString() следует, между прочим, каждый раз оценивать как "class java.lang.Class" . c уже является объектом Class и c.toString() напечатает это, это класс, и каждый последующий класс просто напечатает его.
Показать ещё 2 комментария
Теги:

1 ответ

4
Лучший ответ

Это трудный вопрос, чтобы ответить кратко, честно говоря, потому что (конструктивно и объективно) вам не хватает некоторых фундаментальных концепций работы дженериков.

c - экземпляр Class который является Object как и все остальное. Параметры типового типа должны быть типами, а не объектами. Если вы хотите установить ограничения на свой тип HashMap вам придется выражать эти ограничения в виде общих параметров типа. Например:

public static <T> HashMap<String,T> getEntries (Context context, Type type) {
    HashMap<String,T> hm = new HashMap<String,T>();
    ...
}

Однако, поскольку нет способа вывести тип T из любого из параметров, Class T не всегда доступен в рамках метода. Типичным подходом является добавление некоторого полезного параметра, который также может ограничивать тип, например:

public static <T> HashMap<String,T> getEntries (Context context, Type type, Class<T> clazz) {
    HashMap<String,T> hm = new HashMap<String,T>();
    ...
}

С этим вы можете позвонить следующим образом:

HashMap<String,String> entries = getEntries(context, type, String.class);

И вы также можете использовать clazz мере необходимости в методе.

Надеюсь, этого достаточно, чтобы вдохновить вас двигаться в правильном направлении.

  • 0
    Большое спасибо, это ответило на мой вопрос. Я попробовал это подобным образом и раньше, но я пропустил <T> после статического кода, который закончился ошибкой компилятора.
  • 0
    @ Лукас Рад, что это помогло; Возможно, я связал назначение вашего параметра Type с моим параметром Class<T> в примере, но, надеюсь, вы поняли идею. Если вы имели в виду java.lang.reflect.Type , к сожалению, с интерфейсом Type вы мало что можете сделать; Class как правило, то, что вы хотите придерживаться. Кроме того, в некоторых конкретных случаях вы можете увидеть массивы, используемые для аналогичных целей, например, ArrayList.toArray (обратите внимание, что безпараметрическая версия может возвращать только Object[] ).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню