6

I noticed something in static initializers which may be a bug in the javac. I have constructed a scenario where I can assign a variable a value but not read that value back.

The two examples are below, the first compiles fine, the second gets an error when trying to read a value from tmp, but for some reason assigning a value to tmp is permitted. I could understand if it could neither read nor write to the variable since tmp is declared after the static initializer, but an error on only one of those does not make sense to me.

//Compiles Successfully:
public class Script
{
    public static Object tmp;
    static
    {
        tmp = new Object();
        System.out.println(tmp);
    }

}

//error only on the read but not the assignment
public class Script
{

    static
    {
        tmp = new Object();
        System.out.println(tmp);
    }
    public static Object tmp;
}

to emphasize the point further, this does compile successfully.

public class Script
{

    static
    {
        tmp = new Object();
    }
    public static Object tmp;
}
Raedwald
  • 40,290
  • 35
  • 127
  • 207
S E
  • 2,987
  • 3
  • 19
  • 32
  • I believe [an answer to a similar question][1] answers this question better than I can. It is strange behavior but not a bug. It is doing what it is supposed to be doing. [1]: http://stackoverflow.com/a/10035928/348975 – emory May 07 '13 at 14:03
  • I'm not sure that it does, static initializers are there to initialize the variables from their default value. which is to say static int v = 1; is equivalent to static int v; static{v=1;} – S E May 07 '13 at 14:06
  • @Dukeling I wrote my comment as an answer and StackOverflow determined my answer was trivial (I think that means too short) and automagically converted it to a comment, but evidently flubbed the links. – emory May 07 '13 at 14:12
  • "Gets an error": what error? – Raedwald Jan 19 '16 at 08:32

1 Answers1

3

It seems this is defined in the spec (See JLS 8.3.2.3):

The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:

  • The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer
    of C.

  • The usage is not on the left hand side of an assignment.

  • The usage is via a simple name.

  • C is the innermost class or interface enclosing the usage.

So if the usage is on the left hand side of an assignment, then it is legal, since the second one does not hold anymore.

zw324
  • 25,032
  • 15
  • 79
  • 112
  • Ok, I buy that it is part of the specification, still that seems like a very odd thing to specify – S E May 07 '13 at 14:19
  • Sometimes I think Java needs more than just a spec, but also another book that explain the decisions it makes. I hope someone can shed more light on this, but the spec is the best I can find out. – zw324 May 07 '13 at 14:22