Анализировать JSON для получения списка объектов POJO с использованием класса объектов POJO

Я вынужден использовать метод интерфейса с подписью, которую я не могу изменить:

List parse(String path, Class clazz)

Предполагается вернуть список объектов с типом, переданным в параметре clazz, например:

List<TagsRun> runs = reader.parse(path, TagsRun.class)

Мне нужно реализовать парсер JSON, и вопрос в том, как установить тип параметра clazz в список результатов?

Я использую Gson, и это может быть что-то вроде:

List parse(String path, Class clazz) {
    Type collectionType = new TypeToken<List<TagsRun>>(){}.getType();
    List<TagsRun> myList = new Gson.fromJson(json, collectionType);
    return myList 
}

Но как здесь заменить конкретный Список <TagsRun> на Список <тип clazz>?

Единственное рабочее решение, которое я сделал, требует изменения сигнатуры метода:

<T> List<T> parse(String path, Class<T[]> clazz ) {
        T[] arr = new Gson().fromJson(new File(path).text(), clazz);
        return Arrays.asList(arr);
}

Другими словами, как вернуть список объектов, имеющих тот же тип, что и аргумент clazz, используя сигнатуру:

 List parse(String path, Class clazz)

Заранее спасибо.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
1 552
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Может список преобразовать?

List<TagsRun> myList = new Gson.fromJson(json, collectionType);
List<Clazz> = Arrays.asList(myList.toArray(new Clazz[0]));

Редактировать: Думаю, это может вам помочь: https://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#checkedCollection(java.util.Collection,%20java.lang.Class) - Прокрутите вниз до раздела Список, если вы этого не заметили

Проблема в том, что у меня в методе нет типа ТегиЗапуск. У меня только Класс и не могу установить тип List во время выполнения.

BohdanN 30.10.2018 16:01

какой тип новый Gson.fromJson (json, collectionType); возвращаясь в свой код? Тип объекта может быть решением, преобразовав его позже на другом этапе ?!

theMahaloRecords 30.10.2018 16:10

либо я ошибаюсь, но не могли бы вы просто выполнить List <clazz.getClass ()> ...

theMahaloRecords 30.10.2018 16:23

Нет, я не могу. Поскольку общие списки существуют только во время компиляции, а не во время выполнения. Таким образом, невозможно параметризовать список во время выполнения.

BohdanN 30.10.2018 16:30

Поскольку вы не можете изменить подпись метода, нет смысла возвращать список с параметром типа.

public List foo() {
    ArrayList<String> strings = new ArrayList<>();
    return strings;
}

public void methodUsingFoo() {
    // possible but you should check if the assumption is correct:
    List<String> uncheckedAssignment = foo(); // so don't do this

    // this is what foo *will* return:
    List actualResult = foo();
}

Вместо этого вы можете сделать что-то вроде этого:

public void methodUsingParse() {
    Class clazz = Object.class; // or whatever class you want or need

    // this is what your method *will* return:
    List actualResult = parse("/path/to/somewhere", clazz);

    // best way would be to check each element:
    for(Object element : actualResult) {
        if (clazz.equals(element.getClass())) {
            // do your stuff here
        }
    }
}

Что я забыл: Я не думаю, что это вообще возможно сделать так, как вам хотелось бы.

Ответ принят как подходящий

Решил, наконец:

@Override
List parse(String path, Class clazz) {
    List result = []
    JsonArray jsonArray = new JsonParser()
            .parse(new File(path).getText(CHARSET))
            .getAsJsonArray()

    Gson gson = new Gson()
    jsonArray.each {
        result.add(gson.fromJson(it, clazz))
    }
    return result
}

Хитрость заключается в том, чтобы сначала получить массив, а затем использовать gson.fromJson(it, clazz) для каждого элемента массива. Это преобразует каждый элемент json в массиве в POJO, а затем добавит его в список результатов.

Другие вопросы по теме