Where does the Enum.valueOf(String) method come from?
Asked Answered
I

2

27

In Java SE 7 (and most probably in previous versions) the Enum class is declared like this:

 public abstract class Enum<E extends Enum<E>>
 extends Object
 implements Comparable<E>, Serializable

The Enum class has a static method with this signature:

  T static<T extends Enum<T>> valueOf(Class<T> enumType, String name) 

But there is no static method : valueOf(String) defined in the Enum class nor upwards in the hierarchy Enum belongs to.

The question is where does valueOf(String) come from ? Is it a feature of the language, i.e. a feature built in the compiler ?

Igorot answered 11/8, 2012 at 12:40 Comment(0)
F
25

This method is implicitly defined by the compiler.

From the documentation:

Note that for a particular enum type T, the implicitly declared public static T valueOf(String) method on that enum may be used instead of this method to map from a name to the corresponding enum constant. All the constants of an enum type can be obtained by calling the implicit public static T[] values() method of that type.

From the Java Language Specification, section 8.9.2:

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);
Fedora answered 11/8, 2012 at 12:44 Comment(5)
The reason for not including this method in the set of methods of the Enum class is that an implementation could not be provided until compile time when the returned Enum value is known (which is : an enum object of the type defined by the programmer). Still, an alternative would be to actually declare it as an abstract method in the Enum class and let the compiler provide an implementation at compile-time. Of course, this means it could also be overridden by the user but the compiler could handle also this case. It looks more natural to have the method in the class!Igorot
@Igorot Static methods can't be abstract in Java (or most other languages, I suppose).Sighted
I didn't say static abstract !Igorot
@Igorot You didn't say static, but they are static. Are you suggesting that they should be changed to be non-static? Wouldn't that diminish there usefulness?Sighted
@Sighted It would for sure since you have first to build an instance of an Enum and then invoke valueOf. My proposal was to have the method literally in the class, in the code. Another option would be to have a static method with no implementation and the compiler should provide the implementation at compilation.Igorot
S
0

I think it must be a feature of the language. For one, to create an enum by making one and it does not need to extend Enum:

public enum myEnum { red, blue, green }

That alone, is a language feature or else you would need to do this:

public class  MyEnum extends Enum { ..... }

Secondly, the method, Enum.valueOf(Class<T> enumType, String name), must be produced by the compiler when you you use myEnum.valueOf(String name).

That is what would seem possible given that the new Enum is as much a language feature as it is a class to extend.

Saucer answered 11/8, 2012 at 13:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.