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方法中 thenewField为 1 MyBroadcastReceiver。但是你会得到值 0。

另请参阅以下 SO 问题以获取更多信息和更多可能出现的潜在问题:在 java 构造函数中传递“this”

于 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 回答