简体   繁体   English

可以在最终实例变量声明中使用“ this”吗?

[英]Is it ok to use 'this' in final instance variable declaration?

Is it OK to use the this keyword in a final instance variable declaration/initialization in Java? 在Java的final实例变量声明/初始化中可以使用this关键字吗?

Like this: 像这样:

private final SomeClass foo = new SomeClass(this);

It worked when I tried it out. 当我尝试时它起作用了。 And since it is not a static variable I guess it should be referring to a particular instance. 而且由于它不是static变量,所以我猜它应该引用特定的实例。 But I felt unsure if it is advisable or not so therefore I wanted to ask here. 但是我不确定是否建议这样做,因此我想在这里问一下。

Edit: The main class is an Android Activity class, and the SomeClass-instance needs this Activity as Context. 编辑:主类是Android Activity类,SomeClass实例需要将此Activity作为上下文。

It is "technically valid" to do this. 这样做是“技术上有效的”。 Indeed, this refers to a particular instance - namely, the instance that contains the instance of SomeClass . 实际上, this是指一个特定实例-即包含SomeClass实例的实例。

But I would not recommend to do this in general. 但是我一般建议这样做。 The exact behavior and state of the this that is passed to the constructor depends on subtle details. 传递给构造函数的this的确切行为和状态取决于细微的细节。 Consider the following example: 考虑以下示例:

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;
    }
}

I assume that this could make a neat job interview question, because predicting the output is hard. 我认为这可能会带来一个整洁的工作面试问题,因为很难预测输出结果。 Surprisingly, it prints 令人惊讶的是,它打印

State: 
   a: null
   b: b
   c: c
   d: null
 ref: null

Notice that the final variable c is initialized, but the non-final variable d is not intialized yet. 注意, final变量c已初始化,但非最终变量d 尚未初始化。 In contrast to that, the non-final variable b (that is declared before the SomeClass instance) is already intitialized. 与此相反,非最终变量b (在SomeClass实例之前声明)已经初始化。

Such subtelities are always questionable, and should be avoided if possible. 这样的卑鄙总是令人怀疑的,应该尽可能避免。

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

The SomeClass constructor will find a bar with 0. SomeClass构造函数将找到一个带0的bar

So it is not so fine. 所以不是很好。

My first concern is : why would you need this ? 我首先关心的是:您为什么需要这个?

Generally, I would not recommend this as it could potentially be dangerous in more complex scenarios, where SomeClass construction depends on certain state of passed this object. 通常,我不建议这样做,因为在更复杂的情况下可能存在危险,因为SomeClass构造取决于传递this对象的某些状态。

Consider, for example : 考虑例如:

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
    }
}

and then your Foo class: 然后是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);
}

yes it is fine. 是的,这很好。

as it has nothing to do with the final keyword of the Instance variable. 因为它与Instance变量的final关键字无关。 what you are doing is passing the enclosing class' object to the constructor of SomeClass 您正在做的是将封闭类的对象传递给SomeClass的构造函数

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM