簡體   English   中英

可以在最終實例變量聲明中使用“ this”嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM