3

If you have a Java enum and a variable of the enum's type, as so:

public enum Something
{
   VAL1,
   VAL2,
   VAL3
}

public Something varName;

why is it necessary to write varName = Something.VAL1; instead of simply varName = VAL1;? Shouldn't the compiler know from the type of varName that it can only take null, VAL1, VAL2, and VAL3 as values?

2
  • No. Enum values aren't global (except in switches, it seems). Commented Aug 19, 2015 at 22:49
  • What if Something implements an interface (Serializable, for example), and you want to declare varName as a Serializable. How would the compiler know that you are trying to declare from that particular enum, versus any other serializable type? The language is designed to allow a variable to be typed as any of its supertypes, and this wouldn't be possible with your suggested enum declaration style. Commented Aug 19, 2015 at 22:54

4 Answers 4

5

The righthand side of the = statement is an expression, which is parsed generically. Anyway, to show how it could be complicated for the compiler, consider this:

public enum Something { VAL1, VAL2, VAL3 }

Something VAL3 = Something.VAL1;

Something a = VAL3;

Should a be assigned VAL1 or VAL3?

The only time you don't need the enum name is in a switch statement, because the case statements must use a valid enum value, so the enum name is unnecessary.

switch (a) {
    case VAL1:
        // do something
        break;
    case VAL2:
        // do something
        break;
    case VAL3:
        // do something
        break;
}
Sign up to request clarification or add additional context in comments.

1 Comment

This is a good point, and well stated. I guess, as ruahk suggests in his answer, I don't' hate the readers of my code enough for such a construct to even cross my mind.
4

This is a good question. Offhand, the only reason I can think of is that something like this is perfectly valid (provided you hate the people reading your code):

public class Evil {
     public enum FooBar { FOO, BAR }
     public static FooBar FOO = FooBar.BAR;

     private FooBar baz = FOO;    // means Evil.FOO, i.e. FooBar.BAR
}

Java does have some type inference (for example, final List<String> emptyStringList = java.util.Collections.emptyList() is equivalent to final List<String> emptyStringList = java.util.Collections.<String>emptyList(), and has been since Java 5), but this type inference never alters the meaning of an expression, it only ever selects a single meaning for an otherwise-ambiguous expression.

2 Comments

LOL Like the comment about hating the people that read your code. BTW: It's a coding pattern called "Obfuscation": en.wikipedia.org/wiki/Obfuscation_%28software%29
A good point, especially about hating the readers of your code. I've never hated them enough for such a construct to even cross my mind. Of course, I happen to be the main reader of my code...
1

If you have two enums defining VAL1, how can the compiler know which one are you referring to?

Nevertheless, static imports may make things a bit more readable:

import static Something.VAL1;

1 Comment

By the type, I would assume. It is ever valid to set a variable of type Something to a value of type SomethingElse, when SomethingElse does not inherit from Something?
0

It doesn't, always. It does most of the time to resolve the ambiguity that would arise if all the scopes of all the in-scope enums were automatically opened, but there is one case where it does open the scope of one enum: the switch statement:

Enum MyEnum
{
    Value1;
}
MyEnum value = ...;
switch (myEnumValue)
{
case Value1:
    //
    break;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.