- PR -

staticインスタンスについて

1
投稿者投稿内容
かず
会議室デビュー日: 2005/01/31
投稿数: 8
お住まい・勤務地: 東京(出張)
投稿日時: 2005-02-14 10:04
お世話になってます。かずです。

現在、以下のようなデータクラスを作成しております。
しかし、生成したインスタンスを取得しデータ設定後、別クラスで生成済みの
インスタンスは取得できるのですが、ComboBoxData_の値が消えています。
なぜ値が消えてしまっているのでしょうか??
また、ComboBoxData_をstaticにしても設定した値は消えてしまいます。
ご教授のほどよろしくお願いします。

public class CRCommonData {
//本クラスのインスタンス保持用
private static CRCommonData instanceCRCommonData_ = null;

private Vector ComboBoxData_ = null; //リストデータ

  //インスタンスデータクラス取得
  public static CRCommonData getInstance(){
if(instanceCRCommonData_ == null){
try {
instanceCRCommonData_ = (CRCommonData)CRCommonData.class.newInstance();
} catch(Exception e) {
System.out.println(e.toString());
}
}

return instanceCRCommonData_;
}

/**
*データ設定
*/
public void setComboBoxData(Vector ComboBoxData) {
ComboBoxData_ = ComboBoxData;
}

/**
*データ取得
*/
public Vector getComboBoxData() {
return ComboBoxData_;
}
}
YOU@IT
ぬし
会議室デビュー日: 2002/03/29
投稿数: 284
お住まい・勤務地: 大阪
投稿日時: 2005-02-14 11:06

このクラスを使っている側(クライアント)としては、
コード:
 /* クラスA */
 CRCommonData data = CRCommonData.getInstance();
 Vector combo = new Vector();
 combo.add( ... );
 data.setComboBoxData(combo);


 /* クラスB */
 CRCommonData data = CRCommonData.getInstance();
 Vector combo = data.getComboBoxData();
 /* なぜかcomboがnull */


のような感じなんですよね?
# クラスAとBが別のVM上で動いている...ことはないですよね?

コードを見る限り、問題は無さそうに見えるのですが、
デバッグして思ったような動きをしているか追跡してみてはどうでしょうか?

Sysmem.out.println()でログを出すもよし、Eclipseのデバッガを
使うもよし、だと思います。

パテ太
ベテラン
会議室デビュー日: 2004/08/16
投稿数: 64
お住まい・勤務地: 千葉・東京
投稿日時: 2005-02-14 12:02
引用:

かずさんの書き込み (2005-02-14 10:04) より:

現在、以下のようなデータクラスを作成しております。
しかし、生成したインスタンスを取得しデータ設定後、別クラスで生成済みの
インスタンスは取得できるのですが、ComboBoxData_の値が消えています。

  public static CRCommonData getInstance(){
if(instanceCRCommonData_ == null){
try {
instanceCRCommonData_ = (CRCommonData)CRCommonData.class.newInstance();
} catch(Exception e) {
System.out.println(e.toString());
}
}

return instanceCRCommonData_;
}


パテ太と申します。

あるクラスが生成したインスタンスと
別のクラスの参照したインスタンスは
同一のものでしょうか?

  1. 上記 getInstance() はスレッドセーフではないので
     複数インスタンスが生成されることがあります。
  2. 上記クラスはコンストラクタを持っていないので
     デフォルトコンストラクタにアクセス可能です。
     正規の手順 getInstance() 経由ではなく
     new CRCommonData() でインスタンスの生成が可能です。

ぜんぜん見当違いかもしれませんが
ちょっと気になったので投稿しました。
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2005-02-14 12:15
消えるというのが null になるのか、それとも設定した時とは異なる要素になってしまうのかが不明ですが、もし後者なら

コード:
public void setComboBoxData(Vector ComboBoxData) {
ComboBoxData_ = ComboBoxData;
}



ここが原因ですね。
同じリファレンスを保持するのではなく、ディープコピーにする必要があるかもしれません。

例えば、示されたコードのままでは
コード:
CRCommonData data = CRCommonData.getInstance();
Vector combo = new Vector();
combo.add( ... );
data.setComboBoxData(combo);

combo.remove(0);



ということをすると、combo だけではなく data.ComboBoxData_ の先頭要素も remove されてしまいます。
ただし、
コード:
combo = null;


しても data.ComboBoxData_ は(普通は)null にはなりません。

あと気になった点が二つあります。
(1) 素直に new するのではなくわざわざリフレクションを使っている理由がわからない。
(何らかのフレームワークで発生し、それを単純化して問題が再現する最小限のコードにしたところこうなったのであれば、その点は問題ありません。)
(2) CRCommonData.getInstance() がスレッドセーフでないので、複数のスレッドから呼び出したタイミングによっては競合が発生する。

もし data.ComboBoxData_ の値が null になってしまうのであれば、一般的な原因はわかりません。

YOU@IT さんが利用コード(定義コードではなく)を推測されていますが、かずさんの所で問題が再現する利用コードを示していただければ、より詳しいことがわかるかもしれません。
1

スキルアップ/キャリアアップ(JOB@IT)