可以使用'这个'在最后的实例变量声明?

时间:2014-04-24 09:06:39

标签: java android final

在Java中的this实例变量声明/初始化中使用final关键字是否可以?

像这样:

private final SomeClass foo = new SomeClass(this);

当我试用它时它起作用了。因为它不是static变量,我想它应该指的是一个特定的实例。但我不确定这是否可取,因此我想问这里。

编辑: 主类是Android Activity类,SomeClass-instance需要将此Activity作为Context。

4 个答案:

答案 0 :(得分:4)

这样做“技术上有效”。实际上,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(在<{em} SomeClass实例之前声明为)已经初始化。

这些小事件总是有问题的,如果可能的话应该避免。

答案 1 :(得分:3)

private final SomeClass foo = new SomeClass(this);
private int bar = 42;

SomeClass构造函数将找到bar为0。

所以不太好。

答案 2 :(得分:1)

我首先关注的是:你为什么需要这个?

通常,我不建议这样做,因为在更复杂的情况下它可能会有危险,其中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);
}

答案 3 :(得分:-1)

是的,没关系。

因为它与Instance变量的final关键字无关。 你正在做的是将封闭类的对象传递给SomeClass

的构造函数