2

Say I have this enumerated type of Colours as follows:

public enum Colour
{
    RED, GREEN, BLUE;
}

I want to randomize a colour out of those three, following the suggestion found over there: https://stackoverflow.com/a/8114214/2736228

But I don't want to make a call to values() over and over again, so, I came up with something as follows:

public enum Colour
{
    RED, GREEN, BLUE;

    private static final Colour[] Values = values();

    public static Colour random()
    {
        return Values[(int) (Math.random() * Values.length)];
    }
}

Question is, will it work, always?

What confuses me here, is that when the initialization of this private static final field occurs. It should be happening after the full list of enumeration is completed. I don't see it happening anytime soon, but still, I want to make sure.

Community
  • 1
  • 1
Utkan Gezer
  • 2,794
  • 1
  • 11
  • 27
  • By the way it is proper convention in Java to name final constants with all caps. – M. Shaw Apr 24 '15 at 23:07
  • 1
    but it feels like you waste the final variable, have you measured strong performance improvement comparing to `values()[...]` ? – xerx593 Apr 24 '15 at 23:07
  • @xerx593 No, I haven't measured anything at all. It just didn't feel right that I will be going to create something just momentarily to destroy, though I think it happens anywhere else in my code almost all the time. – Utkan Gezer Apr 24 '15 at 23:09
  • And this doesn't even do what you want: The array is mutable. Be clear and follow convention (use the method) until you have a demonstrated performance problem. – chrylis -cautiouslyoptimistic- Apr 24 '15 at 23:46

1 Answers1

5

Yes, this initialization will always work. The enum constants are always listed first, and the JLS, Section 8.9.3, guarantees that they will be initialized before any other normal static variables.

For each enum constant c declared in the body of the declaration of E, E has an implicitly declared public static final field of type E that has the same name as c. The field has a variable initializer consisting of c, and is annotated by the same annotations as c.

These fields are implicitly declared in the same order as the corresponding enum constants, before any static fields explicitly declared in the body of the declaration of E.

All static fields are initialized in order as if they were a single text block, so all of your enum constants will be initialized before Values is initialized by calling values().

Incidentally, static final variables are usually named with all capitalized letters, e.g. VALUES, per standard Java naming conventions.

Community
  • 1
  • 1
rgettman
  • 167,281
  • 27
  • 248
  • 326
  • 1
    Yes for all, except for the last sentence: [constants, not `static final` variables, should be capitalized](http://www.oracle.com/technetwork/java/codeconventions-135099.html). You want to be pedantic? So am I. A `static final` variable is not always a constant. Example: a `List` that can be updated dynamically can be `static final` but is certainly not a constant. I agree this is not the case here, but it's worth being complete since you felt the need to mention it. – Olivier Grégoire Apr 24 '15 at 23:24
  • 1
    @OlivierGrégoire Well it is a naming standard, and one I like to stick to. Java doesn't really support constant lists syntactically (compile-time), so you would have to use a Immutable list implementation. Immutable lists fail against change only during run-time ... unfortunately ... – YoYo Apr 25 '15 at 02:28
  • 1
    @JoD. Well, please check [this page](https://google-styleguide.googlecode.com/svn/trunk/javaguide.html#s5.2.4-constant-names) which clearly shows the difference between constants and other fields. So the two most popular naming conventions (Sun/Oracle in my previous comment and Google in this one) clearly state that there is a difference between constants and `static final` fields, and both state that only constants should be capitalized. So I fail to see which "naming standard" you're referring to. Would you enlighten me? – Olivier Grégoire Apr 26 '15 at 11:42
  • 1
    @OlivierGrégoire Google, yes, but not so sure about oracle. Oracle/sun's document refers to something named an ANSI constant. That seems to be documentation inherited from C/c++, and otherwise no reference to the immutability of an object. Either way, if that is what you follow, good for you. Me on the other hand, I find it sometimes hard to implement, or sometimes too much overhead to make things completely immutable, so I just declare my intention to use it as a constant. – YoYo Apr 26 '15 at 16:50
  • 1
    @JoD. [Whatever](http://en.wiktionary.org/wiki/constant#Noun) [you](http://www.merriam-webster.com/dictionary/constant) [say](http://dictionary.cambridge.org/dictionary/british/constant). – Olivier Grégoire Apr 27 '15 at 08:30