197

I declare an enum as :

enum Sex {MALE,FEMALE};

And then, iterate enum as shown below :

for(Sex v : Sex.values()){
    System.out.println(" values :"+ v);
}

I checked the Java API but can't find the values() method? I'm curious as to where this method comes from?

API link : https://docs.oracle.com/javase/8/docs/api/java/lang/Enum.html

aioobe
  • 413,195
  • 112
  • 811
  • 826
rai.skumar
  • 10,309
  • 6
  • 39
  • 55

3 Answers3

202

You can't see this method in javadoc because it's added by the compiler.

Documented in three places :

The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared. This method is commonly used in combination with the for-each construct to iterate over the values of an enum type.

  • Enum.valueOf class
    (The special implicit values method is mentioned in description of valueOf method)

All the constants of an enum type can be obtained by calling the implicit public static T[] values() method of that type.

The values function simply list all values of the enumeration.

Justin Standard
  • 21,347
  • 22
  • 80
  • 89
Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • 8
    any specific reason for this? why it's not part of API? – rai.skumar Dec 01 '12 at 12:18
  • 11
    Because using just the standard mechanism (without enum), you couldn't have this static method. The java specification had to be extended to allow those enums, that's why it must be added by the compiler. – Denys Séguret Dec 01 '12 at 12:19
  • 4
    Since Java 7 this has been added to the javadoc of java.lang.Enum, in the description of the static valuOf method. – Catweazle Nov 02 '13 at 14:20
  • 1
    @Catweazle Good observation. I give the link [here](http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html#valueOf). – Denys Séguret Nov 02 '13 at 15:49
  • @Catweazle Funny that it's not listed as its own method. I completely missed that! – Autumn Leonard Dec 21 '15 at 15:57
  • 4
    Does calling "values()" create a new array, or does it re-use the same one? – android developer Jul 05 '16 at 08:35
  • 3
    @androiddeveloper it returns a new array (otherwise you might mess with the enum) – Denys Séguret Jul 05 '16 at 08:37
  • @DenysSéguret I see. Thank you. Do you know if it's written somewhere that this is what's supposed to be? – android developer Jul 05 '16 at 12:32
  • 1
    @androiddeveloper No but it's kind of implicit. It's said that it returns the array containing the values of the enumeration. As an array can't be constant in java, the only way to guarantee the array hasn't been changed (it might be on another thread) is to make a new one. – Denys Séguret Jul 05 '16 at 15:05
  • @DenysSéguret Sure an array can be constant. Just set it as "private static final", and inside a "static" block, initialize it. The values there can be modified, but this doesn't mean it should affect the enum itself, as the values aren't stored there. In any case, thank you. – android developer Jul 05 '16 at 16:08
  • 1
    The values can be modified, that's the point, so you can't share the array, hence you must give a different one at every access. – Denys Séguret Jul 05 '16 at 17:07
39

The method is implicitly defined (i.e. generated by the compiler).

From the JLS:

In addition, if E is the name of an enum type, then that type has the following implicitly declared static methods:

/**
* Returns an array containing the constants of this enum 
* type, in the order they're declared.  This method may be
* used to iterate over the constants as follows:
*
*    for(E c : E.values())
*        System.out.println(c);
*
* @return an array containing the constants of this enum 
* type, in the order they're declared
*/
public static E[] values();

/**
* Returns the enum constant of this type with the specified
* name.
* The string must match exactly an identifier used to declare
* an enum constant in this type.  (Extraneous whitespace 
* characters are not permitted.)
* 
* @return the enum constant with the specified name
* @throws IllegalArgumentException if this enum type has no
* constant with the specified name
*/
public static E valueOf(String name);
NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • `Added by the compiler` means there's no .java for this code or the code is generated by the compiler? I checked the [OpenJDK source code of Enum](http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Enum.java) and there's no `values()` – Marco Sulla May 01 '19 at 14:40
13

Run this

    for (Method m : sex.class.getDeclaredMethods()) {
        System.out.println(m);
    }

you will see

public static test.Sex test.Sex.valueOf(java.lang.String)
public static test.Sex[] test.Sex.values()

These are all public methods that "sex" class has. They are not in the source code, javac.exe added them

Notes:

  1. never use sex as a class name, it's difficult to read your code, we use Sex in Java

  2. when facing a Java puzzle like this one, I recommend to use a bytecode decompiler tool (I use Andrey Loskutov's bytecode outline Eclispe plugin). This will show all what's inside a class

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275