这只是令我困惑的事情。是否可以在构造函数中使用类的当前实例?
我创建了一个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");
}
}
}
答案 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
方法中newField
在MyBroadcastReceiver
构造函数中初始化时为{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());
}
}
它就像一个魅力