8

内部クラス内の変数を変更する必要があり、悪名高い「別のメソッドで定義された内部クラス内の非最終変数を参照できません」というエラーが発生しました。

void onStart(){
  bt.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
       int q = i;
     }
  });
}

私はすぐに、変更したいすべてのものを保持するクラスを作成し、内部クラスの外部でクラスの最終バージョンを作成しました

class temp{
  int q;
}

void onStart(){
  final temp x = new temp();
  bt.setOnClickListener(new View.OnClickListener() {
     public void onClick(View v) {
       x.q = i;
     }
  });
}

これは私が必要としているもののようで、機能しますが、これが問題を正しく回避する方法であるかどうか疑問に思っています。tempまた、クラスに名前を付けるのにこの単語を使用するのは本当に嫌いです。クラスの名前をよりわかりやすくするために、実際に行ったことのプログラミング用語はありますか?

4

4 に答える 4

9

匿名クラスの代わりに内部クラスを作成するだけです (現在行っているように)。次に、メンバーを設定するコンストラクターとその他のメソッドがあります。ハックは必要ありません (1 ケースの配列のように)。

クラスがその外部クラスとのデータ交換を必要とする場合、これはよりクリーンだと思いますが、個人的な好みであることは認めます。1 イディオムの配列も同様に機能し、より簡潔ですが、率直に言って、見栄えが悪いだけです。私は通常、匿名の内部クラスを、外部クラスのデータを更新しようとせずにアクションを実行するだけのものに制限します。

例えば:

private MyListener listener = new MyListener();

void onStart(){
  bt.setOnClickListener(listener);
}

class MyListener implements OnClickListener
{ 
    String name;
    int value;

    void setName(String newName)
    {
        name = newName;
    }

    void setValue(int newValue)
    {
        value = newValue;
    }

    public void onClick(View v) 
    {
        // Use the data for some unknown purpose
    }
}

複数のスレッドが関係している場合は、適切な同期も使用する必要があります。

于 2012-07-03T19:23:28.817 に答える
2

ここの他のスレッドに同様の回答を投稿しました。Object基本的には、ほぼすべてのタイプをラップする「ラッパー」を作成するという考え方です。finalJava では、「定数」ではなく「再割り当てなし」を表すため、このトリックはほとんど問題なく機能します。ただし、元の投稿で述べたように、マルチスレッド環境で使用する場合は注意が必要です。

于 2012-07-03T18:30:34.797 に答える
0

(コメントから)複数のものを設定しているように見えるので、メインクラスにメソッドを作成しbutton1WasClicked()(より適切な名前はdoUpdate、doSaveなど-ボタンの機能に関連するもの)、そこに適切なコードを配置し、内部クラス/リスナーから呼び出します。(Swingを使用している場合は、アクションにします、YMMV)

そうすれば、後で同じことを実行する必要のあるメニュー、インテント、またはジェスチャがある場合、呼び出しがそこにあります。

于 2012-07-03T19:43:15.347 に答える
0

外部クラスでオンクリックリスナーへの参照を保持し、int をリスナーのメンバー変数にします。クリック時に変数をリスナーに保存し、必要なときに外部クラスで変数を取得します。クリックした時点で変数を設定するのではありません。

簡単に言えば、内部クラスで変更する必要がある場合は、内部クラスの変数にします。

于 2012-07-03T19:31:42.607 に答える