Google Gson - ดีซีเรียลไลซ์รายการ‹คลาส› วัตถุ? (ประเภททั่วไป)

ฉันต้องการถ่ายโอนออบเจ็กต์รายการผ่าน Google Gson แต่ฉันไม่ทราบวิธีดีซีเรียลไลซ์ประเภททั่วไป

สิ่งที่ฉันลองหลังจากดู สิ่งนี้ ( คำตอบของ BalusC):

MyClass mc = new Gson().fromJson(result, new List<MyClass>(){}.getClass());

แต่แล้วฉันได้รับข้อผิดพลาดใน eclipse โดยแจ้งว่า "ประเภท new List(){} ต้องใช้วิธีนามธรรมที่สืบทอดมา..." และหากฉันใช้วิธีแก้ไขด่วน ฉันจะได้รับมอนสเตอร์ที่มีเมธอด stub มากกว่า 20 รายการ

ฉันค่อนข้างแน่ใจว่ามีวิธีแก้ไขที่ง่ายกว่านี้ แต่ดูเหมือนจะหาไม่พบ!

แก้ไข:

ตอนนี้ฉันมี

Type listType = new TypeToken<List<MyClass>>()
                {
                }.getType();

MyClass mc = new Gson().fromJson(result, listType);

อย่างไรก็ตาม ฉันได้รับข้อยกเว้นต่อไปนี้ที่บรรทัด "fromJson":

java.lang.NullPointerException
at org.apache.harmony.luni.lang.reflect.ListOfTypes.length(ListOfTypes.java:47)
at org.apache.harmony.luni.lang.reflect.ImplForType.toString(ImplForType.java:83)
at java.lang.StringBuilder.append(StringBuilder.java:203)
at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:56)
at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:88)
at com.google.gson.JsonDeserializationVisitor.visitUsingCustomHandler(JsonDeserializationVisitor.java:76)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:106)
at com.google.gson.JsonDeserializationContextDefault.fromJsonArray(JsonDeserializationContextDefault.java:64)
at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:49)
at com.google.gson.Gson.fromJson(Gson.java:568)
at com.google.gson.Gson.fromJson(Gson.java:515)
at com.google.gson.Gson.fromJson(Gson.java:484)
at com.google.gson.Gson.fromJson(Gson.java:434)

ฉัน ทำ จับ JsonParseExceptions และ "ผลลัพธ์" ไม่เป็นโมฆะ

ฉันตรวจสอบ listType ด้วยดีบักเกอร์และได้รับสิ่งต่อไปนี้:

  • list Type
    • args = ListOfTypes
      • list = null
      • SolvedTypes = ประเภท[ 1 ]
    • ตัวโหลด = PathClassLoader
    • OwnerType0 = โมฆะ
    • OwnerTypeRes = null
    • rawType = คลาส (java.util.ArrayList)
    • rawTypeName = "java.util.ArrayList"

ดูเหมือนว่าการเรียกใช้ "getClass" ทำงานไม่ถูกต้อง ข้อเสนอแนะใด ๆ ... ?

แก้ไข 2: ฉันได้ตรวจสอบ Gson แล้ว คู่มือผู้ใช้ โดยกล่าวถึง Runtime Exception ที่ควรเกิดขึ้นระหว่างการแยกวิเคราะห์ประเภททั่วไปเป็น Json ฉันทำ "ผิด" (ไม่ได้แสดงไว้ด้านบน) เช่นเดียวกับในตัวอย่าง แต่ไม่ได้รับข้อยกเว้นนั้นเลย ดังนั้นฉันจึงเปลี่ยนซีเรียลไลซ์ตามคำแนะนำในคู่มือผู้ใช้ แต่ก็ไม่ได้ช่วยอะไร

แก้ไข 3: แก้ไขแล้ว ดูคำตอบของฉันด้านล่าง


person jellyfish    schedule 05.04.2011    source แหล่งที่มา
comment
คำตอบที่คุณชี้ไป ใช้ TokenType คุณลองวิธีนี้แล้วหรือยัง?   -  person Nishant    schedule 05.04.2011
comment
เพิ่งได้รับคำใบ้เดียวกันกับคำตอบ คราวหน้าผมจะยกตัวอย่างให้ละเอียดยิ่งขึ้น ;)   -  person jellyfish    schedule 05.04.2011
comment
คุณลองใช้ list ในโทเค็นประเภทได้ไหม เนื่องจากประเภทดิบของคุณคือรายการอาร์เรย์ คุณควรลองใช้รายการอาร์เรย์   -  person uncaught_exceptions    schedule 06.04.2011


คำตอบ (14)


วิธีการดีซีเรียลไลซ์คอลเลกชั่นทั่วไป:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

...

Type listType = new TypeToken<ArrayList<YourClass>>(){}.getType();
List<YourClass> yourClassList = new Gson().fromJson(jsonArray, listType);

เนื่องจากมีหลายคนในความคิดเห็นกล่าวถึง ต่อไปนี้เป็นคำอธิบายว่าคลาส TypeToken ใช้งานอย่างไร โครงสร้าง new TypeToken<...>() {}.getType() รวบรวมประเภทเวลาคอมไพล์ (ระหว่าง < และ >) ลงในวัตถุรันไทม์ java.lang.reflect.Type ต่างจากอ็อบเจ็กต์ Class ซึ่งสามารถแสดงเฉพาะประเภท raw (ลบแล้ว) เท่านั้น อ็อบเจ็กต์ Type สามารถแสดงประเภทใดก็ได้ในภาษา Java รวมถึงการสร้างอินสแตนซ์แบบกำหนดพารามิเตอร์ของประเภททั่วไป

คลาส TypeToken นั้นไม่มีตัวสร้างสาธารณะ เนื่องจากคุณไม่ควรสร้างมันโดยตรง แต่คุณมักจะสร้างคลาสย่อยที่ไม่ระบุชื่อเสมอ (ดังนั้น {} ซึ่งเป็นส่วนที่จำเป็นของนิพจน์นี้)

เนื่องจากการลบประเภท คลาส TypeToken จึงสามารถบันทึกเฉพาะประเภทที่ทราบโดยสมบูรณ์ ณ เวลาคอมไพล์เท่านั้น (นั่นคือ คุณไม่สามารถดำเนินการ new TypeToken<List<T>>() {}.getType() สำหรับพารามิเตอร์ประเภท T ได้)

สำหรับข้อมูลเพิ่มเติม โปรดดูเอกสารประกอบสำหรับคลาส TypeToken.

person uncaught_exceptions    schedule 05.04.2011
comment
ใน GSON เวอร์ชันใหม่ ตัวสร้าง TypeToken ไม่ใช่แบบสาธารณะ ดังนั้นที่นี่คุณจะได้รับข้อผิดพลาดตัวสร้างที่มองไม่เห็น คุณต้องทำอะไรในกรณีนี้? - person Pablo; 04.04.2012
comment
การใช้ GSON เวอร์ชันจริง (2.2.4) จะทำงานได้อีกครั้ง คุณสามารถเข้าถึงตัวสร้างได้ที่นี่ - person ; 21.11.2013
comment
วัตถุ json ของฉันเริ่มต้นด้วยวัตถุ จากนั้นมีอาร์เรย์ของวัตถุที่ฉันต้องการ { "myObjectArray":[ {....} , {....} , {....} ] } ฉันได้สร้างไฟล์โมเดลสำหรับ {....} แล้ว ฉันจะรับโค้ดคอลเลกชันทั่วไปนี้ได้อย่างไรเพื่อไม่ให้องค์ประกอบรูทของฉันเป็นอาร์เรย์โดยไม่ต้องสร้างการซ้อนใหม่ ไฟล์วัตถุ - person CQM; 07.02.2014
comment
แพ็คเกจใดที่จำเป็นสำหรับคำสั่ง type.getType() ฉันได้รับ The method getType() is undefed for the type new ArrayList‹XXXX›(){} - person Jose Ospina; 01.03.2015
comment
มันทำให้ฉันเกิดข้อผิดพลาดหากฉันใช้ proguard เพียงอย่างเดียว ไม่อย่างนั้นมันจะใช้งานได้ ข้อเสนอแนะใด ๆ - person Pratik Butani; 07.05.2015
comment
ต้องมีการนำเข้าดังต่อไปนี้ --- import java.lang.reflect.Type; นำเข้า com.google.gson.reflect.TypeToken - person Umair Saleem; 30.06.2015
comment
นี่เป็นสิ่งที่ดีถ้า YourClass ได้รับการแก้ไขในโค้ด จะเกิดอะไรขึ้นถ้าคลาสมาตอนรันไทม์? - person jasxir; 08.09.2015
comment
จากนั้นคุณมักจะพบข้อยกเว้นการส่งคลาส (java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap) เมื่อคุณพยายามใช้งาน - person Jan Rabe; 09.11.2015
comment
{} ก่อนหน้า .getType ดูไม่ใช่ Java สำหรับฉัน ฉันไม่สามารถบอกได้ว่ามันคืออะไรทางวากยสัมพันธ์ มันเป็นคลาสที่ไม่เปิดเผยตัวตนที่ว่างเปล่าหรืออะไร? - person Fermin Silva; 04.08.2016
comment
@CQM คุณมีสองวิธี 1- เพียงลบอักขระตัวแรกและตัวสุดท้ายออกจากสตริงและคุณก็พร้อมแล้ว 2- สร้างคลาสโดยใส่ ArrayList‹Whatever› ของคุณไว้ในคลาสนั้น ตอนนี้แค่ใช้ Anything.class สำหรับการโต้แย้งครั้งที่สอง คุณพร้อมแล้ว - person steve moretz; 27.03.2019
comment
สำหรับโคตลิน val listType = object : TypeToken<ArrayList<YourClass>>() {}.type - person illusionJJ; 27.03.2019

อีกวิธีหนึ่งคือการใช้อาร์เรย์เป็นประเภท เช่น:

MyClass[] mcArray = gson.fromJson(jsonString, MyClass[].class);

วิธีนี้ช่วยให้คุณหลีกเลี่ยงความยุ่งยากกับออบเจ็กต์ Type และหากคุณต้องการรายการจริงๆ คุณสามารถแปลงอาร์เรย์เป็นรายการได้ตลอดเวลาโดย:

List<MyClass> mcList = Arrays.asList(mcArray);

IMHO นี่อ่านง่ายกว่ามาก

และเพื่อให้เป็นรายการจริง (ที่สามารถแก้ไขได้ โปรดดูข้อจำกัดของ Arrays.asList()) จากนั้นให้ดำเนินการดังต่อไปนี้:

List<MyClass> mcList = new ArrayList<>(Arrays.asList(mcArray));
person DevNG    schedule 25.06.2013
comment
มันเยี่ยมมาก! ฉันจะใช้มันสะท้อนแสงได้อย่างไร? ฉันไม่ทราบค่า MyClass และจะมีการกำหนดค่าแบบไดนามิก! - person Amin Sh; 27.12.2013
comment
nota: ด้วยเหตุนี้ โปรดระวังว่า mcList ไม่ใช่รายการที่สมบูรณ์ หลายสิ่งหลายอย่างจะไม่ทำงาน - person njzk2; 05.06.2014
comment
ใช้ร่วมกับยาชื่อสามัญได้อย่างไร? T[] yourClassList = gson.fromJson(message, T[].class); //ไม่สามารถเลือกจากตัวแปรประเภทได้ - person Pawel Cioch; 21.02.2015
comment
@ njzk2 รายการเต็มรูปแบบคืออะไร? - person Mateus Viccari; 05.03.2017
comment
@MateusViccari ในขณะที่แสดงความคิดเห็นนั้น mcList ในคำตอบนี้เป็นเพียงผลลัพธ์ของการเรียกไปที่ Arrays.asList เมธอดนี้จะส่งคืนรายการที่เมธอดทางเลือกส่วนใหญ่หรือทั้งหมดนั้นไม่ได้ถูกนำไปใช้และเกิดข้อยกเว้น ตัวอย่างเช่น คุณไม่สามารถเพิ่มองค์ประกอบใดๆ ลงในรายการนั้นได้ ตามที่การแก้ไขในภายหลังแนะนำ Arrays.asList มีข้อจำกัด และการล้อมไว้ใน ArrayList จริงช่วยให้คุณได้รับรายการที่มีประโยชน์มากกว่าในหลายกรณี - person njzk2; 06.03.2017
comment
อย่าลืมก่อน Gson gson = new Gson(); สำหรับผู้เริ่มต้น - person anshulkatta; 02.09.2017
comment
หากคุณต้องการสร้างประเภทอาร์เรย์ขณะรันไทม์สำหรับประเภทองค์ประกอบที่กำหนดเอง คุณสามารถใช้ Array.newInstance(clazz, 0).getClass() ตามที่อธิบายไว้ใน คำตอบของ David Wood - person Daniel Pryden; 20.03.2018

ตั้งแต่ Gson 2.8 เราสามารถสร้างฟังก์ชัน util ได้ เช่น

public <T> List<T> getList(String jsonArray, Class<T> clazz) {
    Type typeOfT = TypeToken.getParameterized(List.class, clazz).getType();
    return new Gson().fromJson(jsonArray, typeOfT);
}

ตัวอย่างการใช้

String jsonArray = ...
List<User> user = getList(jsonArray, User.class);
person Linh    schedule 21.08.2018
comment
TypeToken#getParameterized ดูดีกว่าการแฮ็กด้วยคลาสย่อยที่ไม่ระบุชื่อ - person Nikolay Kulachenko; 10.10.2018
comment
ฉันคัดลอกวิธีการของคุณตามที่เป็นอยู่และมันใช้งานไม่ได้ : คอมไพเลอร์บอกว่า The method getParameterized(Class‹List›, Class‹T›) is undef for the type TypeToken. ฉันตรวจสอบทั้งเวอร์ชัน Gson (2.8.0) และเอกสารประกอบแล้ว และทุกอย่างเรียบร้อยดีในด้านนี้... ฉันลงเอยด้วยการใช้โซลูชัน @Happier ซึ่งทำงานได้ดี - person leguminator; 20.02.2020
comment
@leguminator คุณนำเข้า TypeToken ถูกต้องหรือไม่ และคุณกำลังใช้ java หรือ kotlin ฉันจะลองทดสอบอีกครั้ง - person Linh; 20.02.2020
comment
@PhanVanLinh แน่นอน: ฉันใช้ Java และนำเข้า com.google.gson.reflect.TypeToken และ java.lang.reflect.Type ฉันเพิ่มการตรวจสอบวิธีการดำเนินการเป็นสองเท่า: มีการประกาศเป็น Public static TypeToken‹?› getParameterized(Type rawType, Type... typeArguments) - person leguminator; 20.02.2020
comment
นี่ควรเป็นโซลูชันที่ได้รับการยอมรับ เรียบง่าย โดยใช้ Gson API และไม่มีการแฮ็กใดๆ +1 - person 4gus71n; 29.08.2020

อ้างถึงโพสต์นี้ ประเภท Java ทั่วไปเป็นอาร์กิวเมนต์สำหรับ GSON

ฉันมีทางออกที่ดีกว่าสำหรับเรื่องนี้ นี่คือคลาส wrapper สำหรับรายการเพื่อให้ wrapper สามารถจัดเก็บประเภทรายการได้อย่างแน่นอน

public class ListOfJson<T> implements ParameterizedType
{
  private Class<?> wrapped;

  public ListOfJson(Class<T> wrapper)
  {
    this.wrapped = wrapper;
  }

  @Override
  public Type[] getActualTypeArguments()
  {
      return new Type[] { wrapped };
  }

  @Override
  public Type getRawType()
  {
    return List.class;
  }

  @Override
  public Type getOwnerType()
  {
    return null;
  }
}

จากนั้นโค้ดก็สามารถทำได้ง่าย:

public static <T> List<T> toList(String json, Class<T> typeClass)
{
    return sGson.fromJson(json, new ListOfJson<T>(typeClass));
}
person Happier    schedule 16.10.2014
comment
mEntity.rulePatternคืออะไร? - person Al Lelopath; 07.04.2015
comment
มันเป็นเพียงวัตถุตัวอย่างสำหรับการทดสอบ คุณไม่จำเป็นต้องสนใจเรื่องนี้ ใช้วิธี toList และทุกอย่างเป็นไปด้วยดี - person Happier; 08.04.2015

Wep อีกวิธีหนึ่งในการบรรลุผลเดียวกัน เราใช้มันเพื่อให้อ่านง่าย

แทนที่จะทำประโยคที่อ่านยากนี้:

Type listType = new TypeToken<ArrayList<YourClass>>(){}.getType();
List<YourClass> list = new Gson().fromJson(jsonArray, listType);

สร้างคลาสว่างที่ขยายรายการวัตถุของคุณ:

public class YourClassList extends ArrayList<YourClass> {}

และใช้มันเมื่อแยกวิเคราะห์ JSON:

List<YourClass> list = new Gson().fromJson(jsonArray, YourClassList.class);
person Roc Boronat    schedule 27.11.2015

สำหรับ Kotlin เพียง:

import java.lang.reflect.Type
import com.google.gson.reflect.TypeToken
...
val type = object : TypeToken<List<T>>() {}.type

หรือนี่คือฟังก์ชันที่มีประโยชน์:

fun <T> typeOfList(): Type {
    return object : TypeToken<List<T>>() {}.type
}

จากนั้นเพื่อใช้:

val type = typeOfList<YourMagicObject>()
person Chad Bingham    schedule 25.10.2017
comment
ฉันใช้รหัสของคุณเพื่อสร้างฟังก์ชันนี้โดยใช้ประเภท reified: inline fun <reified T> buildType() = object : TypeToken<T>() {}.type!! และเรียกมันด้วยประเภทรายการ: buildType<List<YourMagicObject>>() - person coffeemakr; 21.11.2017
comment
@coffeemakr คุณไม่จำเป็นต้องมีประเภท reified ที่นี่ - person Chad Bingham; 22.11.2017
comment
โอ้. แต่ทำไมคุณถึงสร้างโทเค็นประเภทของ ArrayList ใน buildType และยังเรียกใช้ฟังก์ชันด้วยประเภททั่วไปด้วย นี่เป็นการพิมพ์ผิดหรือเปล่า? - สิ่งนี้จะสร้าง ArrayList‹ArrayList‹YourMagicObject›› - person coffeemakr; 23.11.2017
comment
@coffeemakr อ๋อ ใช่ครับ พิมพ์ผิด - person Chad Bingham; 23.11.2017

public static final <T> List<T> getList(final Class<T[]> clazz, final String json)
{
    final T[] jsonToObject = new Gson().fromJson(json, clazz);

    return Arrays.asList(jsonToObject);
}

ตัวอย่าง:

getList(MyClass[].class, "[{...}]");
person kayz1    schedule 02.03.2015
comment
สิ่งที่ดี. แต่คำตอบนี้ซ้ำกับ DevNGs ข้างต้นซึ่งเขียนเมื่อ 2 ปีก่อนหน้านี้: stackoverflow.com/a/17300003/1339923 (และอ่านคำตอบนั้น สำหรับคำเตือนสำหรับแนวทางนี้) - person Lambart; 27.09.2017

เนื่องจากเป็นการตอบคำถามเดิมของฉัน ฉันจึงยอมรับคำตอบของ doc_180 แล้ว แต่หากมีใครพบปัญหานี้อีก ฉันจะตอบคำถามครึ่งหลังของฉันด้วย:

NullPointerError ที่ฉันอธิบายไม่เกี่ยวข้องกับรายการเลย แต่มีเนื้อหาด้วย!

คลาส "MyClass" ไม่มีคอนสตรัคเตอร์ "no args" และไม่มีคลาสซูเปอร์คลาสด้วย เมื่อฉันเพิ่มตัวสร้าง "MyClass()" แบบธรรมดาให้กับ MyClass และซูเปอร์คลาสของมัน ทุกอย่างทำงานได้ดี รวมถึงรายการการทำให้เป็นอนุกรมและการดีซีเรียลไลซ์ตามที่แนะนำโดย doc_180

person jellyfish    schedule 08.04.2011
comment
หากคุณมีรายการคลาสนามธรรม คุณจะได้รับข้อผิดพลาดเดียวกัน ฉันเดาว่านี่เป็นข้อความแสดงข้อผิดพลาดทั่วไปของ GSON สำหรับ ไม่สามารถสร้างอินสแตนซ์ของคลาสได้ - person Drew; 30.09.2011
comment
เคล็ดลับเกี่ยวกับการเพิ่ม Constructor ช่วยให้ฉันรู้ว่าเหตุใดฉันจึงมีค่า Null ทั้งหมด ฉันมีชื่อฟิลด์เช่น To และ From ในสตริง JSON ของฉัน แต่ฟิลด์ที่เกี่ยวข้องในออบเจ็กต์ของฉันเป็นแบบไปและกลับด้วยตัวพิมพ์เล็ก ดังนั้นฟิลด์เหล่านั้นจึงถูกข้ามไป - person Rune; 19.06.2016

นี่คือโซลูชันที่ใช้งานได้กับประเภทที่กำหนดแบบไดนามิก เคล็ดลับคือการสร้างประเภทอาร์เรย์ที่เหมาะสมโดยใช้ Array.newInstance()

    public static <T> List<T> fromJsonList(String json, Class<T> clazz) {
    Object [] array = (Object[])java.lang.reflect.Array.newInstance(clazz, 0);
    array = gson.fromJson(json, array.getClass());
    List<T> list = new ArrayList<T>();
    for (int i=0 ; i<array.length ; i++)
        list.add(clazz.cast(array[i]));
    return list; 
}
person David Wood    schedule 31.03.2016

ฉันต้องการเพิ่มความเป็นไปได้อีกอย่างหนึ่ง หากคุณไม่ต้องการใช้ TypeToken และต้องการแปลงอาร์เรย์อ็อบเจ็กต์ json เป็น ArrayList คุณสามารถดำเนินการดังนี้:

หากโครงสร้าง json ของคุณเป็นดังนี้:

{

"results": [
    {
        "a": 100,
        "b": "value1",
        "c": true
    },
    {
        "a": 200,
        "b": "value2",
        "c": false
    },
    {
        "a": 300,
        "b": "value3",
        "c": true
    }
]

}

และโครงสร้างชั้นเรียนของคุณเป็นดังนี้:

public class ClassName implements Parcelable {

    public ArrayList<InnerClassName> results = new ArrayList<InnerClassName>();
    public static class InnerClassName {
        int a;
        String b;
        boolean c;      
    }
}

จากนั้นคุณสามารถแยกวิเคราะห์ได้ดังนี้:

Gson gson = new Gson();
final ClassName className = gson.fromJson(data, ClassName.class);
int currentTotal = className.results.size();

ตอนนี้คุณสามารถเข้าถึงแต่ละองค์ประกอบของวัตถุ className

person Apurva Sharma    schedule 14.08.2015

อ้างถึงตัวอย่างที่ 2 สำหรับความเข้าใจคลาส 'ประเภท' ของ Gson

ตัวอย่างที่ 1: ใน deserilizeResturant นี้ เราใช้อาร์เรย์ Employee[] และรับรายละเอียด

public static void deserializeResturant(){

       String empList ="[{\"name\":\"Ram\",\"empId\":1},{\"name\":\"Surya\",\"empId\":2},{\"name\":\"Prasants\",\"empId\":3}]";
       Gson gson = new Gson();
       Employee[] emp = gson.fromJson(empList, Employee[].class);
       int numberOfElementInJson = emp.length();
       System.out.println("Total JSON Elements" + numberOfElementInJson);
       for(Employee e: emp){
           System.out.println(e.getName());
           System.out.println(e.getEmpId());
       }
   }

ตัวอย่างที่ 2:

//Above deserilizeResturant used Employee[] array but what if we need to use List<Employee>
public static void deserializeResturantUsingList(){

    String empList ="[{\"name\":\"Ram\",\"empId\":1},{\"name\":\"Surya\",\"empId\":2},{\"name\":\"Prasants\",\"empId\":3}]";
    Gson gson = new Gson();

    // Additionally we need to se the Type then only it accepts List<Employee> which we sent here empTypeList
    Type empTypeList = new TypeToken<ArrayList<Employee>>(){}.getType();


    List<Employee> emp = gson.fromJson(empList, empTypeList);
    int numberOfElementInJson = emp.size();
    System.out.println("Total JSON Elements" + numberOfElementInJson);
    for(Employee e: emp){
        System.out.println(e.getName());
        System.out.println(e.getEmpId());
    }
}
person Ram Patro    schedule 10.09.2017

ฉันชอบคำตอบจาก kays1 แต่ไม่สามารถนำไปใช้ได้ ดังนั้นฉันจึงสร้างเวอร์ชันของตัวเองโดยใช้แนวคิดของเขา

public class JsonListHelper{
    public static final <T> List<T> getList(String json) throws Exception {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        Type typeOfList = new TypeToken<List<T>>(){}.getType();
        return gson.fromJson(json, typeOfList);
    }
}

การใช้งาน:

List<MyClass> MyList= JsonListHelper.getList(jsonArrayString);
person mike83_dev    schedule 20.10.2015
comment
แน่นอนว่าสิ่งนี้ใช้ไม่ได้เนื่องจากคุณพยายามใช้ T ในเวลาคอมไพล์ สิ่งนี้จะทำการดีซีเรียลไลซ์ไปยังรายการ StringMap อย่างมีประสิทธิภาพใช่ไหม - person JHH; 04.04.2017

ในกรณีของฉัน คำตอบของ @uncaught_Exceptions ใช้งานไม่ได้ ฉันต้องใช้ List.class แทน java.lang.reflect.Type:

String jsonDuplicatedItems = request.getSession().getAttribute("jsonDuplicatedItems").toString();
List<Map.Entry<Product, Integer>> entries = gson.fromJson(jsonDuplicatedItems, List.class);
person Andrei    schedule 24.03.2017

ฉันได้สร้าง GsonUtils lib สำหรับกรณีนี้ ฉันเพิ่มสิ่งนี้ลงในที่เก็บกลาง maven

Map<String, SimpleStructure> expected = new HashMap<>();
expected.put("foo", new SimpleStructure("peperoni"));

String json = GsonUtils.writeValue(expected);

Map<String, SimpleStructure> actual = GsonUtils.readMap(json, String.class, SimpleStructure.class);
person oleg.cherednik    schedule 11.01.2021