1

I have that enum:

enum MyNameIsDynamic {
  LOW,
  MEDIUM,
  HIGH
}

And now the question is:
It is possible to create dynamically instance of that based only on its name? I mean something like that:

Instead of this:

MyNameIsDynamic myEnum;
String valueOfEnum = myEnum.LOW.toString();

I want something like that:

String nameOfMyEnum = "MyNameIsDynamic";
Enum(nameOfMyEnum) myEnum; //Name of enum based on string
String valueOfEnum = myEnum.LOW.toString();

Well i don't know how to exactly show what i want, but i hope that "strange" example above will be enough.
I know it is possible with object based on Class's name, but is it too with Enums?
Please help me guys if that question is not abstract ^_^

6
  • When you know the name of the enum, what do you need this workaround for? Commented May 11, 2020 at 5:36
  • How would you use this? Are you suggesting you have multiple Enum's with a .LOW value? Commented May 11, 2020 at 5:37
  • Related: stackoverflow.com/questions/9886266/… Commented May 11, 2020 at 5:37
  • I have many enums and I need to extract their content based on the name. I am writing an application to convert types. If I choose a type from the list, I need to dynamically generate a list of types to which the selected type can be converted. This information is contained in enums. For example, I have "JavaEnum" and there is information that java can be converted to TypeScript and Python. Commented May 11, 2020 at 5:43
  • 1
    What you want is not possible. You could go for dynamic programing and work with class tokens over reflection but it really sounds like your architecture/approach is just not good and should be improved instead. I would suggest you share a concrete snippet of your real code and then people could come up with better designs. Commented May 11, 2020 at 6:05

3 Answers 3

3

Just like with objects, you cannot create a left hand name. So you can get your enum constant though.

public class Enunck{
    enum Junk{
        A,B;
    }
    public static void main(String[] args) throws Exception{
        Class<?> X = Class.forName("Enunck$Junk");
        for(Object o: X.getEnumConstants()){
            System.out.println(o);
        }
        Enum<?> e = (Enum<?>)X.getEnumConstants()[0];
    }
}

That will show all of the enum constants, and even cast one of the constants to an Enum. You won't be able to get it to say. `"Junk" e = ...;

Sign up to request clarification or add additional context in comments.

1 Comment

That is exactly what i need. Thanks matt :D
3

Enum objects automatically instantiated

You said:

create dynamically instance

Instances of an enum are made only once: when the class is loaded. Each constant name on that element is automatically assigned an instance of the enum`s class. Without resorting to some reflection/introspection sorcery, you cannot otherwise instantiate enum objects.

Enum::toString

The toString method generates a String object holding the text of the constant name.

Enum.valueOf

To go the other direction, starting with a constant name, and wanting to get an enum object, call valueOf.

Example

enum FanSpeed {
  LOW,
  MEDIUM,
  HIGH
}

Access one of the already-instantiate objects:

FanSpeed initialSpeed = FanSpeed.LOW ;

Or achieve the same effect by name:

FanSpeed initialSpeed = 
        Enum.valueOf( 
            FanSpeed.class , 
            "LOW" 
        )
;

Or use the shorter version via the enum class itself: FanSpeed.valueOf( "LOW" ).

This string-based approach is generally not necessary. By definition, all of the enum’s objects are known at compile-time. So you should be passing around the enum objects, not their names.

Be aware that the two approaches shown above both access an object that has already been instantiated when your enum class loaded. Neither approach does any instantiation, except indirectly by causing the enum’s class to load.

Class name by Reflection

If your goal is to get the class of the enum by name, use reflection.

The class named Class represents a particular class. To obtain a Class object for a particular class, call Class.forName while passing the name of the desired class as a string.

Class.forName( "com.basil.FanSpeed" )

Verify that the class is indeed an enum by calling Class::isEnum.

From that Class object, you can get an array of all the enum’s objects by calling getEnumObjects.

Obtain a specific enum object via this Class object by passing the constant name to Enum.valueOf as seen above.

Enum.valueOf( 
    Class.forName( "com.basil.FanSpeed" ) ,
    "LOW"
)

Caveat: Use reflection only as a last resort. Often, use of reflection is a “code smell”, indicative of a design strategy needing revision.

7 Comments

Well thanks for answer but we have a little misunderstanding there. The problem is "FanSpeed" is unknown. I can't declare enum like that. I need to get enum Class (FanSpeed) using parameter. Something like that: "FanSpeed" initialSpeed;
@Brarord See my section added to the end.
While it's not what the OP asks for, it should be noted that Enum.valueOf(MyEnum.class, "LOW") can be simplified to MyEnum.valueOf("LOW") using a method that is synthesized by the compiler.
@StephanHerrmann That syntax does not track with the direction of the Answer leading to Class.forName. But I added a mention, for the sake of completeness. Thank you.
"So you should be passing around the enum objects, not their names". One common case where you don't have the enum object is user input from a selection of choices. There you want your code to use the type-safe enum, which you have to create at some point from user input or a GUI class, which typically does not know about your enum.
|
2

Java makes sure that the instance of enum will be created only once, in fact you could create singletons with enums.

Anyway I couldn't totally understand your requirements so I would like to share 2 code snippets that might be helpful:

Snippet 1 - totally dynamic approach:

Here you know only string name of enum class (MyNameIsDynamic) I've placed it in a default package but in general the first like would require full package name like com.example.MyNameIsDynamic

Class cl = Class.forName("MyNameIsDynamic");
Enum low1 = Enum.valueOf(cl, "LOW");
System.out.println(low1 + " " + low1.getClass().getName());

Snippet 2

MyNameIsDynamic low2 = MyNameIsDynamic.valueOf("LOW");
System.out.println(low2 + " " + low2.getClass().getName());

In this approach you know what the class and the string value (LOW)

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.