Tôi đang viết một số mã sẽ được sử dụng để truy xuất tài nguyên từ một trang web. Tất cả đều trông như thế này:Tôi làm cách nào để sử dụng Google GSON để deserialize một mảng JSON thành một Bộ sưu tập của một loại chung?
public Collection<Project> getProjects() {
String json = getJsonData(methods.get(Project.class)); //Gets a json list, ie [1, 2, 3, 4]
Gson gson = new Gson();
Type collectionType = new TypeToken<Collection<Project>>() {}.getType();
return gson.fromJson(json, collectionType);
}
Vì vậy, tự nhiên tôi đã thử abstracting nó bằng cách sử dụng Java Generics.
/*
* Deserialize a json list and return a collection of the given type.
*
* Example usage: getData(AccountQuota.class) -> Collection<AccountQuota>
*/
@SuppressWarnings("unchecked")
public <T> Collection<T> getData(Class<T> cls) {
String json = getJsonData(methods.get(cls)); //Gets a json list, ie [1, 2, 3, 4]
Gson gson = new Gson();
Type collectionType = new TypeToken<Collection<T>>(){}.getType();
return (Collection<T>) gson.fromJson(json, collectionType);
}
Phiên bản chung của mã này không hoạt động.
public void testGetItemFromGetData() throws UserLoginError, ServerLoginError {
Map<String,String> userData = GobblerAuthenticator.authenticate("[email protected]", "mypassword");
String client_key = userData.get("client_key");
GobblerClient gobblerClient = new GobblerClient(client_key);
ArrayList<Project> machines = new ArrayList<Project>();
machines.addAll(gobblerClient.getData(Project.class));
assertTrue(machines.get(0).getClass() == Project.class);
Log.i("Machine", gobblerClient.getData(Project.class).toString());
}
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.gobbler.synchronization.Machine
at com.gobblertest.GobblerClientTest.testGetItemFromGetData(GobblerClientTest.java:53)
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:169)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:154)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:545)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1551)
Lớp trong câu hỏi:
import java.util.Map;
public class Project {
private int total_bytes_stored;
private String name;
private String user_data_guid;
private int seqnum;
private String guid;
private Map current_checkpoint;
private Map<String, String> upload_folder;
// TODO: schema_version
private boolean deleted;
// TODO: download_folders
public Project() {} // No args constructor used for GSON
}
Tôi không khá quen thuộc với tất cả các chi tiết của Java Generics hoặc internals GSON và tìm kiếm của tôi đã không được đặc biệt thông tin. Có một loạt các câu hỏi ở đây trên SO, nhưng hầu hết chỉ đề cập đến các phương pháp triển khai thực hiện như phương pháp gốc mà tôi có. Và GSON docs dường như không bao gồm trường hợp cụ thể này. Vì vậy, một lần nữa, làm thế nào tôi có thể sử dụng Google GSON để deserialize một mảng JSON vào một Bộ sưu tập của một loại chung?
Tốt để nghe, nếu chỉ để cung cấp cho đóng cửa. Tôi hiểu chủ đề có thể là một chút liên quan, nhưng bạn có thể giải thích tại sao một thời gian ngắn? –
Để tương thích ngược và thực hiện đơn giản, JVM không biết các loại đằng sau các tham số kiểu khi chạy. Thông thường bạn không quan tâm, nhưng đây là một trong những tình huống mà bạn làm. Web có rất nhiều bài viết về "tẩy xoá Java" có nhiều chi tiết hơn. –
Thực ra bạn có thể, kiểm tra câu trả lời được đưa ra bởi @jevon http://stackoverflow.com/a/12576189/608805 – raukodraug