2017-09-22 29 views
0

我有我的對象實現了PropertyChangeSupport,但是當我從json字符串反序列化時,變量propertyChangeSupport應該是null,儘管我在默認構造函數中使用new PropertyChangeSupport(this)來初始化該值。我如何使用Gson來正確地初始化或反序列化它?如何在從JSON(Gson)反序列化時初始化PropertyChangeSupport?

說我有這個對象:

public class Blah implements BlahInterface { 
    private PropertyChangeSupport propertyChangeSupport; 

    protected int id; 
    protected BlahType type; 

    public Blah() { 
     propertyChangeSupport = new PropertyChangeSupport(this); 
    } 

    public int getId() { 
     return id; 
    } 

    public void setId(int id) { 
     this.id = id; 
    } 

    public BlahType getType() { 
     return type; 
    } 

    public void setType(BlahType type) { 
     this.type = type; 
    } 

    public void addPropertyChangeListener(PropertyChangeListener listener) { 
     this.propertyChangeSupport.addPropertyChangeListener(listener); 
    } 

    public PropertyChangeListener[] getPropertyChangeListeners() { 
     return this.propertyChangeSupport.getPropertyChangeListeners(); 
    } 
} 

我也試圖把new PropertyChangeSupport(this);直接在開始並沒有去任何一種。我想避免手動編寫一個函數,如initializePropertyChangeSupport(),然後在反序列化後手動調用它,因爲這很醜陋。

我想要做的事:

JsonArray ja = json.get("blahs").getAsJsonArray(); 
ja.forEach(item -> { 
    Blah blah = BlahInterface.Parse(item.toString()); 
    // But here I can't addPropertyChangeListener because propertyChangeSupport is null 
    // vvvvvvvvvvvv 
    blah.addPropertyChangeListener(new PropertyChangeListener() { 

     @Override 
     public void propertyChange(PropertyChangeEvent evt) { 
      BlahState state = (BlahState) evt.getNewValue(); 
      Logger.debug("Property had been updated, " + state.toString()); 
     } 
    }); 
}); 

這是我的JSON解析功能:

@SuppressWarnings("unchecked") 
public static <T extends Blah> T Parse(String json) { 
    Gson gson = new Gson(); 

    Blah t = new Blah(gson.fromJson(json, Blah.class)); 
    switch (t.getType()) { 
     case blahone: 
      return (T) gson.fromJson(json, BlahOne.class); 
     default: 
      return (T) t; 
    } 
}; 
+0

你在哪裏在任何地方啓動通知方法? –

+0

另外,如何在對象存在之前將偵聽器添加到對象中?我不清楚**屬性更改監聽器將會聽到什麼**屬性 - 應該是這個類的* bound *屬性?如果它是'id'屬性,那麼setter方法需要調用支持對象的通知方法。 –

+0

我在反序列化我的json對象後添加了我的'PropertyChangeListener',基本上我從服務器得到一個json字符串,然後將這些數據反序列化到我的'Blah'對象中,然後嘗試將我的'PropertyChangeListener'添加到它。問題是變量爲空,因爲它不是json字符串的一部分,但我試圖避免醜陋的黑客... – codenamezero

回答

0

這個問題的解決方案是我的對象,以實現InstanceCreator<T>。因此,當Gson試圖反序列化對象時,它會調用createInstance函數,該函數反過來返回一個適當的對象,並且PropertyChangeSupport變量被初始化。下面的示例代碼:

public class Blah implements InstanceCreator<Blah> { 
    private final transient PropertyChangeSupport pcs = new PropertyChangeSupport(this); 

    ... 

    public void addPropertyChangeListener(PropertyChangeListener listener) { 
     this.pcs.addPropertyChangeListener(listener); 
    } 

    public void removePropertyChangeListener(PropertyChangeListener listener) { 
     this.pcs.removePropertyChangeListener(listener); 
    } 

    @Override 
    public Blah createInstance(Type type) { 
     return new Blah(); 
    } 
} 

注:臨時關鍵字是存在的pcs只是讓GSON將序列中跳過它,否則GSON會拋出異常。