Recursive initializer works when I add “this”?

后端 未结 3 739
难免孤独
难免孤独 2020-12-03 06:38

This fails to compile (with an illegal forward reference error), as one would expect:

class test {
    int x = x + 42;
}

But t

3条回答
  •  生来不讨喜
    2020-12-03 07:24

    It is too difficult to discover and forbid all accesses to x during x's initialization. For example

    int x = that().x;                |    int x = getX();
                                     |
    Test that(){ return this; }      |    int getX(){ return x; }
    

    The spec stops at "access by simple name" and does not try to be more comprehensive.

    In another section, "Definite Assignment", the spec does the similar thing. For example

    public class Test
    {
        static final int y;
        static final int z = y;  // fail, y is not definitely assigned 
        static{ y = 1; }
    }
    
    public class Test
    {
        static final int y;
        static final int z = Test.y;  // pass... because it's not a simple name
        static{ y = 1; }
    }
    

    Interestingly, "Definite Assignment" specifically mentions that this.x is equivalent to x

    (or, for a field, the simple name of the field qualified by this)

    this clause could be added to the section quoted by NPE as well.

    • the usage is via a simple name (or a simple name qualified by this)

    But in the end, it is impossible at compile time to analyze all possible usages/accesses to a field.

提交回复
热议问题