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