[英]Is it ok to use 'this' in final instance variable declaration?
在Java的final
實例變量聲明/初始化中可以使用this
關鍵字嗎?
像這樣:
private final SomeClass foo = new SomeClass(this);
當我嘗試時它起作用了。 而且由於它不是static
變量,所以我猜它應該引用特定的實例。 但是我不確定是否建議這樣做,因此我想在這里問一下。
編輯:主類是Android Activity類,SomeClass實例需要將此Activity作為上下文。
這樣做是“技術上有效的”。 實際上, this
是指一個特定實例-即包含SomeClass
實例的實例。
但是我一般不建議這樣做。 傳遞給構造函數的this
的確切行為和狀態取決於細微的細節。 考慮以下示例:
class SomeClass
{
public SomeClass(DangerousSelfReference dangerousSelfReference)
{
System.out.println("State: ");
System.out.println(" a: "+dangerousSelfReference.getA());
System.out.println(" b: "+dangerousSelfReference.getB());
System.out.println(" c: "+dangerousSelfReference.getC());
System.out.println(" d: "+dangerousSelfReference.getD());
System.out.println(" ref: "+dangerousSelfReference.getRef());
}
}
public class DangerousSelfReference
{
public static void main(String[] args)
{
DangerousSelfReference d = new DangerousSelfReference();
}
private String a;
private String b = "b";
private final SomeClass ref = new SomeClass(this);
private final String c = "c";
private String d = "d";
DangerousSelfReference()
{
a = "a";
}
String getA()
{
return a;
}
String getB()
{
return b;
}
String getC()
{
return c;
}
String getD()
{
return d;
}
SomeClass getRef()
{
return ref;
}
}
我認為這可能會帶來一個整潔的工作面試問題,因為很難預測輸出結果。 令人驚訝的是,它打印
State:
a: null
b: b
c: c
d: null
ref: null
注意, final
變量c
已初始化,但非最終變量d
尚未初始化。 與此相反,非最終變量b
(在SomeClass
實例之前聲明)已經初始化。
這樣的卑鄙總是令人懷疑的,應該盡可能避免。
private final SomeClass foo = new SomeClass(this);
private int bar = 42;
SomeClass構造函數將找到一個帶0的bar
。
所以不是很好。
我首先關心的是:您為什么需要這個?
通常,我不建議這樣做,因為在更復雜的情況下可能存在危險,因為SomeClass
構造取決於傳遞this
對象的某些狀態。
考慮例如:
class SomeClass {
private Foo foo;
SomeClass(Foo foo) {
this.foo = foo;
// do something based on state of foo
// such as call
int len = foo.myString.length(); // <- this will throw NPE, because
// foo.myString is still null as Foo() constructor wasn't called yet
}
}
然后是Foo課:
class Foo {
String myString = null;
Foo() {/*constructor 1, perhaps calling init()*/
init();
}
Foo(...params) {/*constructor 2*/}
private void init() {
// some initialization
myString = "test String";
}
// Note: this constructor is called before any of Foo's
// constructos are invoked
// thus passed Foo "this" object is not initialized yet
// (contains defaults for all fields)
private final SomeClass someClass = new SomeClass(this);
}
是的,這很好。
因為它與Instance變量的final
關鍵字無關。 您正在做的是將封閉類的對象傳遞給SomeClass
的構造函數
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.