繁体   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