是否可以在构造函数中使用此类实例?

时间:2012-09-01 08:40:43

标签: java android constructor broadcastreceiver this

这只是令我困惑的事情。是否可以在构造函数中使用类的当前实例?

我创建了一个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 个答案:

答案 0 :(得分:1)

如果你在构造函数代码中引用this,那么是 - 它完全有效,否则构造函数实际上不能在自己的实例中构造。然而,我建议遵循常规做法并为您的类成员添加前缀(最常用的前缀是'm'),这有助于避免有时难以调试的问题。所以而不是:

protected Context                       context;
protected MyOnBroadcastReceivedListener listener;
你会得到:

protected Context                       mContext;
protected MyOnBroadcastReceivedListener mListener;

答案 1 :(得分:1)

是的,没有任何麻烦。

在构造函数中,已经创建了对象,但是仍然没有向java代码的其余部分返回引用。您可以毫无后顾之忧地使用this

无论如何,在一些可以自动初始化某些属性的框架中(Context Dependent Injection,CDI),不可能在构造函数中完全初始化类(因为这些属性仍然不可用且可能需要)。这些框架依赖于您将方法标记为@PostConstruct;在设置了所有属性后,将调用该方法(只是让你知道它找到它时的含义)。

答案 2 :(得分:0)

你可以这样做,但不是一个好的风格。从类构造函数内部传递this是危险的,因为当前仍在构造的对象可能未完全初始化。

例如,您可能有一天会向MyBroadcastReceiver添加一个新的int字段,但忽略您有语句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方法中newFieldMyBroadcastReceiver构造函数中初始化时为{1}}。但是你会得到值0。

另请参阅以下SO问题,以获取更多信息以及可能出现的更多潜在问题:Passing "this" in java constructor

答案 3 :(得分:-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());
    }
}

它就像一个魅力