2

それは私を困惑させるものです。コンストラクター内でクラスの現在のインスタンスを使用することは可能ですか?

BroadcastReceiver のコンストラクター内のコンテキストに自身を登録する BroadcastReceiver を作成しました。さらに、再度登録を解除します。これがスタイルいいの?

これが私の例です:

public class MyBroadcastReceiver extends BroadcastReceiver {

    protected Context                       context;
    protected MyOnBroadcastReceivedListener listener;
    protected int                           receiverId;
    protected String                        receiverTag;

    public MyBroadcastReceiver(int receiverId, Context context, MyOnBroadcastReceivedListener listener, String receiverTag) {
        super();

        this.context = context;
        this.listener = listener;
        this.receiverId = receiverId;
        this.receiverTag = receiverTag;

        IntentFilter intentFilter = new IntentFilter(receiverTag);

        context.registerReceiver(this, intentFilter);   // <--- Look at the use of this here
    }

    public void detach() {
        if (context != null) {
            context.unregisterReceiver(this);   // <--- Look at the use of this 
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // ...
        if (listener != null) {
            listener.onBroadcastReceived(receiverId, "Bla", "Blub");
        }
    }
}
4

4 に答える 4

1

コンストラクターコードで使用することを参照する場合this、はい-それは完全に有効です。そうしないと、コンストラクターは自分のインスタンス内で実際に構築することができません。ただし、一般的な慣行に従い、クラス メンバーにプレフィックスを付けることをお勧めします (最も一般的に使用されるプレフィックスは「m」です)。これにより、デバッグが困難な場合がある問題を回避できます。したがって、代わりに:

protected Context                       context;
protected MyOnBroadcastReceivedListener listener;

あなたが持っているでしょう:

protected Context                       mContext;
protected MyOnBroadcastReceivedListener mListener;
于 2012-09-01T08:46:42.677 に答える
1

はい、まったく問題ありません。

コンストラクター内で、オブジェクトが作成されましたが、残りの Java コードへの参照はまだ返されていません。安心してご利用いただけますthis

とにかく、一部の属性が自動的に初期化されるフレームワーク (Context Dependent Injection、CDI) では、コンストラクターでクラスを完全に初期化することはできません (そのような属性はまだ利用できず、必要になる可能性があるため)。@PostConstructこれらのフレームワークは、メソッドを;としてマークすることに依存しています。すべての属性が設定された後、そのメソッドが呼び出されます (見つけたときにそれが何を意味するかがわかります)。

于 2012-09-01T08:47:09.060 に答える
0

あなたはこれを行うことができますが、良いスタイルではありません. クラス コンストラクター内からの受け渡しthisは、現在まだ構築中のオブジェクトが完全に初期化されていない可能性があるため、危険です。

たとえば、ある日、新しい int フィールドを に追加するかもしれませMyBroadcastReceiverんが、ステートメントがあることを見落としcontext.registerReceiver(this, intentFilter);、コンストラクターの最後に新しいフィールドの初期化を追加します。

public MyBroadcastReceiver(int receiverId, Context context, MyOnBroadcastReceivedListener listener, String receiverTag) {
    super();

    this.context = context;
    this.listener = listener;
    this.receiverId = receiverId;
    this.receiverTag = receiverTag;

    IntentFilter intentFilter = new IntentFilter(receiverTag);

    context.registerReceiver(this, intentFilter);   // <--- Look at the use of this here

    this.newField = 1;
}

ここで、コンストラクターで初期化されるため、Context.registerReceiverメソッドで the が 1 になると予想するかもしれません。しかし、値は 0 になります。newFieldMyBroadcastReceiver

詳細および発生する可能性のある問題については、次の SO の質問も参照してください: Passing "this" in Java constructor

于 2012-09-01T08:51:14.530 に答える
-1

はい、動作します。簡単なテストケースを試しました。そしてそれは動作します。:

public class Test {
    private int variable;
    private Test2 test2;

    public Test(int variable, Test2 test2) {
        this.variable = variable;
        this.test2 = test2;
        test2.printTest(this);
    }

    public int getVariable() {
        return variable;
    }

    public static void main(String[] args) {
        Test test = new Test(111111,new Test2());
    }
}
class Test2{

    Test2() {
    }

    public void printTest(Test test){
        System.out.println(test.getVariable());
    }
}

そして、それは魅力のように機能します

于 2012-09-01T08:51:03.653 に答える