fastJson десериализация общего процесса к тому, что я могу узнать

будет анализировать JSON

В нашей повседневной работе кодирования, часто сталкиваются с такой постановкой или JSon структура

{
  "resultcode": "200",
  "reason": "成功的返回",
  "result": {
    "area": "浙江省温州市平阳县",
    "sex": "男",
    "birthday": "1989年03月08日"
  }
}
复制代码

Для поставщика интерфейса, внешний слой , resultcode reasonи resultэти три элемента есть. Таким образом, мы можем определить такой Responseкласс

public class Response<T> {
    private String resultcode;

    private String reason;

    private T result;

}
复制代码

Использование дженериков , чтобы решить , что конечный результат будет заполнен изнутри. Конечно, здесь наполнен объектом, мы условно его можно определить как Userкласс

public class User {
    private String area;
    private String sex;
    private String birthday;
}
复制代码

Таким образом, наши данные будут в соответствии с согласованными правилами JSon, например, возвращается вызывающему. Как абонент, аппарат получает эти данные, мы тогда должны определить следующий классResopnseUser

public class ResopnseUser {
    private String resultcode;

    private String reason;

    private User result;
}

public class User {
    private String area;
    private String sex;
    private String birthday;
}
复制代码

Тогда мы можем использовать fastJson рады разрешить

        String  testJson = "{\"resultcode\":\"200\",\"reason\":\"成功的返回\",\"result\":{\"area\":\"浙江省温州市平阳县\",\"sex\":\"男\",\"birthday\":\"1989年03月08日\"}}";
        ResponseUser response1 =  JSONObject.parseObject(testJson,ResponseUser.class);

复制代码

Мы можем видеть, это было получить результаты, которые мы хотим

Думая улучшения

Тем не менее, это имеет менее серьезные последствия. Я стыковка с каждым провайдером интерфейса, вы должны сгенерировать соответствующий класс. С течением времени эти специальные классы будут становиться все более и более, будут более глубоко вложенными. Поскольку поставщик может абстрагировать Responseкласс, то я могу иметь дело с этим к провайдеру?

        String  testJson = "{\"resultcode\":\"200\",\"reason\":\"成功的返回\",\"result\":{\"area\":\"浙江省温州市平阳县\",\"sex\":\"男\",\"birthday\":\"1989年03月08日\"}}";
        Response<User> response =  JSONObject.parseObject(testJson,Response.class);
复制代码

К сожалению, наши результаты не ожидается, только анализ данных , внешний успешна, внутренний слой resultостается JSONObject.

Обращение к универсальному форуму

Лаки вещь, в которой тысячи инженеров не только думали о таком подходе, и есть кто - то , чтобы решить такую проблему! Вниз через различный поиск, мы нашли fastJson предоставляет TypeReferenceэтот класс может решить наши проблемы.

String  testJson = "{\"resultcode\":\"200\",\"reason\":\"成功的返回\",\"result\":{\"area\":\"浙江省温州市平阳县\",\"sex\":\"男\",\"birthday\":\"1989年03月08日\"}}";
        Response<User> response =  JSONObject.parseObject(testJson,new TypeReference<Response<User>>(){});
复制代码

Ну, у нас есть результаты, которые вы хотите, вы можете, наконец, единый интерфейс для всех внешнего слоя суждения возвращаемого значения.

Не останавливаться на достигнутом

И так далее, мы не нашли каких - либо вопросов для меня? Дженерик будут выполнять во время компиляции типа стирания ах! Это первый раз , когда мы непосредственно использовать Response<User> response = JSONObject.parseObject(testJson,Response.class);недопустимую Причину. Таким образом, даже если мы уже писали , так new TypeReference<Response<User>>(){}не то же самое будет стерта его? Это время выполнения , как добраться до фактического типа мы определили? Глядя на TypeReferenceисходный код, исходный код, к счастью , очень просто и меньше кода. Во- первых , введите в его конструктор protected TypeReference(), с помощью отладки мы обнаружили , что реализация второй строки в коде, он получил письменное наши дженерики.

        Type superClass = getClass().getGenericSuperclass();

        Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
复制代码

Этот код очень прост, добраться до родительского класса , getGenericSuperclass()чтобы добраться до фактического типа. Продолжайте следить код, мы можем видеть , что он вызывает нативный метод , private native String getGenericSignature0();чтобы получить какую - то информацию в класс и родительский класс ClassRepositoryи Type. В это время, мы оглядываемся на new TypeReference<Response<User>>(){}самом деле создать TypeReferenceанонимный внутренний класс по классу getGenericSuperclass(), получить информацию о типе.

Продолжить выкорчевать

Давайте теперь посмотрим на наши доходы, примечание должно быть 2:00:

  1. Дженерик будут выполнять во время компиляции типа стирания .
  2. Для того, чтобы приобрести его родительский класс , getGenericSuperclass()чтобы добраться до фактического типа. И т.д., эти два взаимно противоречивые ах. 1 сказал , что нет, два said'll найти, в конце концов, как это случилось? Глядя на байткод скомпилированных файлов, мы нашли ответ.
    Это код , который содержит Response<User> response = JSONObject.parseObject(testJson,new TypeReference<Response<User>>(){});информацию о методах файл класса декомпилировать. Мы можем видеть , что это еще один LocalvariableTypeTable, который Signatureточно тип информации , хранящейся в актуальной. ** Это не полностью удалить тип, параметр типа мы все еще можем получить путем отражения. ** называемый метод стирания только codeбайт - код стирания свойства. Кроме того, мы также видим InnerClassesсписок, есть внутренний класс называется Main $ 1, это то , что мыnew TypeReference<Response<User>>(){}

резюме

  1. По JSONObject.parseObject(testJson,new TypeReference<Response<User>>(){});пути, чтобы решить эту проблему JSon вложенных дженерик. Удобный, быстрый и интуитивно понятный
  2. Вы можете getClass().getGenericSuperclass();добраться до реального типа. Код аутентификации
  // 这类创建了一个HashMap的匿名子类
        HashMap<String,Integer> subIntMap = new HashMap<String,Integer>(){};

        System.out.println(subIntMap.getClass().getSuperclass());

        Type subClassType = subIntMap.getClass().getGenericSuperclass();
        if(subClassType instanceof ParameterizedType){
            ParameterizedType p = (ParameterizedType) subClassType;
            for (Type t : p.getActualTypeArguments()){
                System.out.println(t);
            }
        }
复制代码

выход

class java.util.HashMap
class java.lang.String
class java.lang.Integer
复制代码
  1. Тип не полностью стерта, тип параметра можно получить с помощью отражения. Код аутентификации
 ResponseUser response = new ResponseUser();
        Field field = response.getClass().getField("result");
        System.out.println("result Type is "+ field.getType());
        System.out.println("result GenericType is "+ field.getGenericType());
public class ResponseUser {
    private String resultcode;

    private String reason;

    public List<User> result;
}
复制代码

выход

result Type is interface java.util.List
result GenericType is java.util.List<com.jd.jr.alpha.cpa.fastJson.User>
复制代码

рекомендация

отjuejin.im/post/5d4aa5ab6fb9a06b297536bb