如何在从JSON(Gson)反序列化时初始化PropertyChangeSupport?

问题描述:

我有我的对象实现了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

这个问题的解决方案是我的对象,以实现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会抛出异常。