FastJson解析を使用する場合の内部クラスに関する2つの問題
3029 ワード
1、内部クラス階層が間違っている
モデルクラスがあるとします.コードは次のとおりです.
注意rowsはDataの変数ですが、クラスRowはDataと同じ階層であり、Modelクラスの内部クラスです.
この場合、解析が必要なjsonは次のようになります.
{
"code":0,
"data":{
"pageSize":20,
"rows":[
{
"id":13
}
]
}
}
FastJsonで解析すると次のエラーが表示されます.
Exception in thread "main"com.alibaba.fastjson.JSONException: create instance error, class com.example.testand.Model$Ds
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:89)
.
.
at com.example.testand.Demo.main(Demo.java:24)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
.
.
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:86)
... 16 more
RowをDataの内部クラスに変更すると、次のような問題が解決します.
2、直接内部クラスで解析する
同様にmodelクラスがあると仮定します.コードは次のとおりです.
この場合、Jsonデータのセットが次のように仮定されます.
{
"rows": [
{
"id": 1
}
]
}
次のコードを使用してデータを解析すると
Data data = JSON.parseObject(jsonStr, Data.class);
同じようにエラーが発生します.
Exception in thread "main"com.alibaba.fastjson.JSONException: create instance error, class com.example.testand.Model$Data
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:89)
.
.
at com.example.testand.Demo.main(Demo.java:25)
Caused by: java.lang.NullPointerException
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:86)
... 7 more
これは,内部クラスを直接用いてjsonを解析するためである.
非静的内部クラスは、次のようにインスタンス化できないことを知っています.
Model.Data data = new Model.Data()
コンパイル中にエラーが発生します.静的でない内部クラスをインスタンス化するには、次のような外部クラスのインスタンスが必要です.
Model model = new Model();
Model.Data data = model.new Date();
これにより、FastJsonがデータを解析する際に内部クラスDataのインスタンスを直接作成するため、上記の方法がエラーになる理由が説明されます.
適切な方法は、内部クラスではなくDataクラスを個別にクラスとして使用することです.次のようにします.
モデルクラス
dataクラス
モデルクラスがあるとします.コードは次のとおりです.
public class Model {
public Data data;
public class Data {
public List rows;
}
public class Row{
}
}
注意rowsはDataの変数ですが、クラスRowはDataと同じ階層であり、Modelクラスの内部クラスです.
この場合、解析が必要なjsonは次のようになります.
{
"code":0,
"data":{
"pageSize":20,
"rows":[
{
"id":13
}
]
}
}
FastJsonで解析すると次のエラーが表示されます.
Exception in thread "main"com.alibaba.fastjson.JSONException: create instance error, class com.example.testand.Model$Ds
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:89)
.
.
at com.example.testand.Demo.main(Demo.java:24)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
.
.
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:86)
... 16 more
RowをDataの内部クラスに変更すると、次のような問題が解決します.
public class Model {
public Data data;
public class Data {
public List rows;
public class Row{
}
}
}
2、直接内部クラスで解析する
同様にmodelクラスがあると仮定します.コードは次のとおりです.
public class Model {
public Data data;
public class Data {
public List rows;
public class Row{
}
}
}
この場合、Jsonデータのセットが次のように仮定されます.
{
"rows": [
{
"id": 1
}
]
}
次のコードを使用してデータを解析すると
Data data = JSON.parseObject(jsonStr, Data.class);
同じようにエラーが発生します.
Exception in thread "main"com.alibaba.fastjson.JSONException: create instance error, class com.example.testand.Model$Data
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:89)
.
.
at com.example.testand.Demo.main(Demo.java:25)
Caused by: java.lang.NullPointerException
at com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer.createInstance(JavaBeanDeserializer.java:86)
... 7 more
これは,内部クラスを直接用いてjsonを解析するためである.
非静的内部クラスは、次のようにインスタンス化できないことを知っています.
Model.Data data = new Model.Data()
コンパイル中にエラーが発生します.静的でない内部クラスをインスタンス化するには、次のような外部クラスのインスタンスが必要です.
Model model = new Model();
Model.Data data = model.new Date();
これにより、FastJsonがデータを解析する際に内部クラスDataのインスタンスを直接作成するため、上記の方法がエラーになる理由が説明されます.
適切な方法は、内部クラスではなくDataクラスを個別にクラスとして使用することです.次のようにします.
モデルクラス
public class Model {
public Data data;
}
dataクラス
public class Data {
public List rows;
public class Row{
}
}