2013-07-22 94 views
2

我希望將所有List s反序列化爲不可修改的集合。反序列化列表使用gson不可修改的集合

這裏是我的課,我反序列化:

public class MyClass 
{ 
    public final mylist = Collections.unmodifiablelist(new ArrayList()); 
} 

如何反序列化:

MyClass inst = (new Gson()).fromJson("{mylist:[\"firstString\"]}", MyClass.class); 

我不想必須建立一個對所有100個類註冊類型的適配器使用List,那麼是否有一種方法可以全局覆蓋的那個實例的可反序列化List

+0

「mylist」字段的類型在哪裏? – PomPom

回答

0

我會用適配器工廠去了,但是短代碼:

class MyAdapter implements TypeAdapterFactory { 

    @Override 
    public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> tokenType) { 
    final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, tokenType); 

    return new TypeAdapter<T>() { 
     @Override 
     public void write(JsonWriter out, T value) throws IOException { 
     delegate.write(out, value); 
     } 

     @Override 
     public T read(JsonReader arg0) throws IOException { 
     T t = delegate.read(arg0); 
     if (List.class.isAssignableFrom(tokenType.getRawType())) { 
      List<?> list = (List<?>) t; 

      return (T) Collections.unmodifiableList(list); 
     } 

     return t; 
     } 
    }; 
    } 
} 

然後,像往常一樣,r egister it:

Gson g = new GsonBuilder().registerTypeAdapterFactory(new MyAdapter()).create(); 
1

爲什麼不遵循JavaBean標準,只返回不可修改的列表?

public class MyClass { 
    private List<String> myList = new ArrayList<String>(); 

    public void setMyList(List<String> list) { 
     this.myList = list; 
    } 

    public Collection<String> getMyList() { 
     return Collections.unmodifiablelist(this.myList); 
    } 
} 
+0

...因爲'myList'實例在內部使用...我寧願爲了理智的原因,讓它不可修改。 – Cheetah

+0

imho,如果你不能相信你自己的班級不做修改,那麼你就有更大的問題 – epoch

+0

......這不是一種信任的事情......如果有人來日後編輯我的班級,更多關於推理的內容。如果它是不可修改的,它會使開發人員停下來,並思考爲什麼這樣做... – Cheetah

0

隨着Gson新版本,你可以創建自定義TypeAdapterFactoryList性能。我實施了簡單的UnmodifiableListTypeAdapter,但我不確定一切正常。請閱讀文檔,瞭解如何正確實施它。

class ListTypeAdapterFactory implements TypeAdapterFactory { 

    @SuppressWarnings({ "rawtypes", "unchecked" }) 
    @Override 
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) { 
     Type type = typeToken.getType(); 
     if (typeToken.getRawType() != List.class || !(type instanceof ParameterizedType)) { 
      return null; 
     } 

     Type elementType = ((ParameterizedType) type).getActualTypeArguments()[0]; 
     TypeAdapter<?> elementAdapter = gson.getAdapter(TypeToken.get(elementType)); 

     return new UnmodifiableListTypeAdapter(elementAdapter); 
    } 
} 

class UnmodifiableListTypeAdapter<E> extends TypeAdapter<List<E>> { 

    private TypeAdapter<E> elementAdapter; 

    public UnmodifiableListTypeAdapter(TypeAdapter<E> elementAdapter) { 
     this.elementAdapter = elementAdapter; 
    } 

    @Override 
    public List<E> read(JsonReader reader) throws IOException { 
     if (reader.peek() == JsonToken.NULL) { 
      reader.nextNull(); 
      return null; 
     } 

     List<E> list = new ArrayList<E>(); 
     reader.beginArray(); 
     while (reader.hasNext()) { 
      E element = elementAdapter.read(reader); 
      list.add(element); 
     } 
     reader.endArray(); 

     return Collections.unmodifiableList(list); 
    } 

    @Override 
    public void write(JsonWriter writer, List<E> list) throws IOException { 
     if (list == null) { 
      writer.nullValue(); 
      return; 
     } 

     writer.beginArray(); 
     for (E item : list) { 
      elementAdapter.write(writer, item); 
     } 
     writer.endArray(); 
    } 
} 

用法示例可能看起來像這樣:

public class GsonProgram { 

    public static void main(String[] args) throws Exception { 
     GsonBuilder gsonBuilder = new GsonBuilder(); 
     gsonBuilder.registerTypeAdapterFactory(new ListTypeAdapterFactory()); 
     Gson gson = gsonBuilder.create(); 

     System.out.println(gson.fromJson("{strings:[\"firstString\"],integers:[23,34,56]}", 
       Entity.class)); 
    } 
} 

class Entity { 

    private List<String> strings; 
    private List<Integer> integers; 

    public List<String> getStrings() { 
     return strings; 
    } 

    public void setStrings(List<String> strings) { 
     this.strings = strings; 
    } 

    public List<Integer> getIntegers() { 
     return integers; 
    } 

    public void setIntegers(List<Integer> integers) { 
     this.integers = integers; 
    } 

    @Override 
    public String toString() { 
     return "Entity [strings=" + strings + ", integers=" + integers + "]"; 
    } 
} 

上面的程序打印:

Entity [strings=[firstString], integers=[23, 34, 56]]