2017-09-22 11 views
0

オブジェクトはPropertyChangeSupportに実装されていますが、デフォルトのコンストラクタでnew PropertyChangeSupport(this)という値を自分自身で初期化しても、変数propertyChangeSupportnullになります。 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);を入れてみましおよびnoのいずれかに行くされています

は、私は、このオブジェクトを持っていると言います。私は親切に、手動で 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

また、オブジェクトにリスナーを追加するにはどうすればいいですか?私はちょうど** **どのプロパティがプロパティリスナーがリッスンすることになるのか明確ではない - このクラスの*束縛されたプロパティであると思われるものは何ですか?それが 'id'プロパティの場合、setterメソッドはサポートオブジェクトの通知メソッドを呼び出す必要があります。 –

+0

私は自分のjsonオブジェクトを逆シリアル化した後に 'PropertyChangeListener'を追加します。基本的にサーバーからjson文字列を取得し、そのデータを' Blah'オブジェクトに逆シリアル化してから 'PropertyChangeListener'を追加しようとします。 。問題は変数がjson文字列の一部ではないので変数がnullであることですが、私は醜いハックを避けようとしています... – 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(); 
    } 
} 

注:transientキーワードは、そうでない場合はGsonが例外をスローしますGsonはシリアル化中にそれをスキップする場合と同じようpcsにあります。

関連する問題