代码之家  ›  专栏  ›  技术社区  ›  codenamezero

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

  •  0
  • codenamezero  · 技术社区  · 7 年前

    PropertyChangeSupport ,但当我从json字符串反序列化时,变量 propertyChangeSupport null ,尽管我用一个 new PropertyChangeSupport(this) 在默认构造函数中。如何使用Gson正确初始化或反序列化它?

    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;
        }
    };
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   codenamezero    7 年前

    这个问题的解决方案是实现 InstanceCreator<T> 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将引发异常。