Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static members not initialized as expected

The following code simply subtracts a value (10 in this case, just for the demonstration) from the current year obtained by using the java.util.Calendar class.

public final class Test
{   
    private static final Test TEST = new Test();
    private static final int YEAR = Calendar.getInstance().get(Calendar.YEAR);
    private final int eval=YEAR - 10;

    public static void main(String[] args)
    {
        System.out.println("Evaluation "+TEST.eval);
    }
}

I expect this code to display 2003 (current year - 10) but instead, it displays -10. I assume the constant YEAR hasn't been initialized. Why does this happen in this case?

like image 704
Tiny Avatar asked Apr 22 '13 23:04

Tiny


4 Answers

This happens because you are initializing Test before you have initialized YEAR - meaning it will go to the (implicit) constructor and initialize eval to YEAR-10 before YEAR has a value (so it defaults to 0).

As denoted in the comments, simply changing the order of YEAR and TEST in the initialization will do the trick.

like image 138
ddmps Avatar answered Oct 24 '22 02:10

ddmps


Because it's not static - you have to create an object in order to use this field! (or change it to static)

Try:

public final class Test
{   
    private static final Test TEST = new Test();
    private static final int YEAR = Calendar.getInstance().get(Calendar.YEAR);    
    private final int eval=YEAR - 10;

    public static void main(String[] args)
    {
        Test t = new Test();
        System.out.println("Evaluation "+t.eval);
    }
}
like image 41
Nir Alfasi Avatar answered Oct 24 '22 01:10

Nir Alfasi


Make eval static and it will work. If you do not want it static, then do the computation in the main method.

like image 28
devang Avatar answered Oct 24 '22 00:10

devang


As others have mentioned, the problem is in the order of the static fields. But, you can avoid the ordering problem entirely by lazily initializing TEST using a method (like is done in the singleton pattern):

public final class Test
{   
    private static Test TEST = null;
    private static final Test getInstance() {
        if (TEST == null) {
            TEST = new Test();
        }
        return TEST;
    }

    private static final int YEAR = Calendar.getInstance().get(Calendar.YEAR);
    private final int eval=YEAR - 10;

    public static void main(String[] args)
    {
        System.out.println("Evaluation "+Test.getInstance().eval);
    }
}
like image 41
Kevin K Avatar answered Oct 24 '22 00:10

Kevin K