8

Why does valueOf have two parameters?

in Java documentation for valueOf

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

Parameters:

enumType - the Class object of the enum type from which to return a constant

name - the name of the constant to return

But most examples I read online says:

enum WorkDays {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY;
}

Test:

WorkDays day1 = WorkDays.valueOf("MONDAY");
System.out.println(day1); // >>>  MONDAY

It seems that the method used only one parameter?

Community
  • 1
  • 1
jxie0755
  • 1,682
  • 1
  • 16
  • 35
  • 3
    Please read the documentation you referenced. –  Mar 20 '19 at 16:03
  • The entire second paragraph. –  Mar 20 '19 at 16:06
  • I actually find it confusing.....and still don't understand... – jxie0755 Mar 20 '19 at 16:07
  • 1
    Possible duplicate of [Understanding Enums in Java](https://stackoverflow.com/questions/1419835/understanding-enums-in-java) – Lino Mar 20 '19 at 16:08
  • In a nutshell it says that you can do what you did. As I understand, The method you use is compiler-generated. –  Mar 20 '19 at 16:12
  • the two arguments method is declared in the `Enum` class, but there are also implicitly declared methods `values` and `valueOf`: [8.9.3. Enum Members](https://docs.oracle.com/javase/specs/jls/se12/html/jls-8.html#jls-8.9.3). You could also have called `Enum.valueOf(WorkDays.class, "MONDAY")` – user85421 Mar 20 '19 at 16:12

3 Answers3

7

As you indicated in previous comments that you find the text in the documentation confusing, and since your profile indicates you are a novice programmer:

Enum is the superclass of all enums you will declare. In your example, WorkDays can be seen as a specific case of the Enum class. The valueOf() static method documentation is writen for this parent Enum class. Meaning that in your case, it would be called as: Enum.valueOf(WorkDays.class, "MONDAY").

Now, since you made your own Enum (i.e. WorkDays), you don't need to use this static parent method. You can just use the method that is exposed by your self-created enum.

WorkDays.valueOf("Monday")

This is "implicitly declared" meaning that it will be there for every one of your self-created enums.

Stijn Dejongh
  • 157
  • 1
  • 1
  • 5
4

The snippet you shared uses the implicitly declared method referenced in the second paragraph:

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.

The first paragraph refers to calling the method via the Enum class:

System.out.println(Enum.valueOf(WorkDays.class, "MONDAY"));
Mureinik
  • 297,002
  • 52
  • 306
  • 350
2

You can just examine the bytecode to see what happens when an enum is compiled:

public enum TestEnum {A, B}

And the bytecode of valueOf:

// access flags 0x9
public static valueOf(Ljava/lang/String;)LTestEnum;
 L0
  LINENUMBER 1 L0
  LDC LTestEnum;.class
  ALOAD 0
  INVOKESTATIC java/lang/Enum.valueOf (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
  CHECKCAST TestEnum
  ARETURN
 L1
  LOCALVARIABLE name Ljava/lang/String; L0 L1 0
  MAXSTACK = 2
  MAXLOCALS = 1

I am no expert in byte code but you can see that the line:

INVOKESTATIC java/lang/Enum.valueOf (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;

In fact invokes java.lang.Enum.valueOf. A java equivalent would look like this:

public static TestEnum myValueOf(String name) {
    return Enum.valueOf(TestEnum.class, name);
}

And the bytecode confirms this:

// access flags 0x9
public static myValueOf(Ljava/lang/String;)LTestEnum;
 L0
  LINENUMBER 6 L0
  LDC LTestEnum;.class
  ALOAD 0
  INVOKESTATIC java/lang/Enum.valueOf (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
  CHECKCAST TestEnum
  ARETURN
 L1
  LOCALVARIABLE name Ljava/lang/String; L0 L1 0
  MAXSTACK = 2
  MAXLOCALS = 1

Comparing these two snippets you can see the difference is... yes, the name (and the line number):

enter image description here

Lino
  • 19,604
  • 6
  • 47
  • 65