3

An odd thought occurred to me. Since Java allows final variables to be set only once, then if I could initialize a variable to itself I could effectively have an uninitialized variable. Now, of course, the following does not work because the compiler appropriately complains "The blank final field TEST may not have been initialized":

public class Test
{
    public static final int TEST;

    static
    {
        TEST = TEST;
    }

    public static void main(String[] args)
    {
        System.out.println(Test.TEST);
    }
}

But with a slight modification, I can get this to compile, and print the "uninitialized value" that I could not print before. (See Below) is this designed to be part of the language? Upon running this several times in a row interspersed with other programs, toggling swap on and off, etc., I've seen both the output "0" and "1" get printed from this function which tells me this truly is an uninitialized value of whatever happened to be floating around in memory there. Is this a bug?

public class Test
{
    public static final int TEST;

    static
    {
//      TEST = TEST;
        TEST = initialValue();
    }

    public static int initialValue()
    {
        return Test.TEST;
    }

    public static void main(String[] args)
    {
        System.out.println(TEST);
    }
}
Kimchy
  • 501
  • 8
  • 24
  • 4
    I don't believe you've seen a 1 for that second test. Java doesn't have "undefined" behavior like that to read "whatever happened to be floating around in memory there". – Sotirios Delimanolis Aug 23 '17 at 18:35
  • @Sotirios Delimanolis I don't know what to tell you, I can run some more tests and try to reproduce it again. –  Aug 23 '17 at 18:38
  • 1
    If it _were_ whatever happened to be in that random bit of memory, which it wasn't, then the chance of it being a 1 is 1 in 4294967296. Anyway, the answer to "why it's allowed to compile" is that Java isn't sophisticated enough to catch that bug in your program. The language has to balance helpfulness (finding that usage of an un-initialized field), simplicity for people to understand, and simplicity of cases for the language designers to consider. – yshavit Aug 23 '17 at 18:38
  • Related: https://stackoverflow.com/questions/24990691/will-java-final-variables-have-default-values. I'll find one for `static` specifically. – Sotirios Delimanolis Aug 23 '17 at 18:39
  • @yshavit that assumes that all numbers have equal probablility which is not true. –  Aug 23 '17 at 18:41
  • @SE Okay, sure. I was estimating. But the chance of it only ever being a 0 or 1 is very low. – yshavit Aug 23 '17 at 18:44
  • 1
    Anyway, I just ran it 1000 times and never got anything other than 0. If you really do get a 1 with the _exact_ code above, then I think you've found a JVM bug... but I suspect that the "1" came from different code which you mistakenly ran. – yshavit Aug 23 '17 at 18:48
  • @yshavit that could be, I'll run some overnight tests and see if anything shows up –  Aug 23 '17 at 18:51
  • 2
    This code always prints `0` as it is a default value for `int` type class member. The other question is why Java allows that code to compile? It should do much better job in checking a static content. – MaxZoom Aug 23 '17 at 18:53
  • So many answers for instance members, can't find one for `static`...https://stackoverflow.com/questions/33995384/why-attempt-to-print-uninitialized-variable-does-not-always-result-in-an-error-m/33995656 – Sotirios Delimanolis Aug 23 '17 at 19:09
  • 1
    As far as I know, all variables (final or not) are internally initialized with their default values. final is just a keyword for the compiler to force you to explicitely initialize it (and it fails in that case...) – Dorian Gray Aug 23 '17 at 19:15

0 Answers0