0

I am attempting to recreate from a JSON string, a collection that holds enum constants (the source of the JSON string). I'm having difficulty figuring out how to recreate the enum from a string. The enums hold a variety of methods which I need access to.

The answers I've seen this and this one, result in a class which enables you to iterate through the constants rather than recreating the original enum. I want to pass the enums around other existing classes without having to rewrite code to cope with a new class.

Is this even possible? Can you use a JSON string to help recreate an enum in such a way you can use it as an enum?

EDIT: Bizarre, I have a big red banner telling me Stack Overflow requires external Javascript and now I cannot comment on posts...

Thanks Brian for your reply below, but it appears in essence to be the same as the two I linked to here, it does not result in you actually having the enum object, just the constants via a different method.

Community
  • 1
  • 1
Matt Stevens
  • 1,104
  • 1
  • 12
  • 24
  • Erm, it does result in you having your enum object ... there's no such thing as "just the constants" in Java. I've edited the answer to demonstrate that fully. – Brian Roach Feb 18 '13 at 17:23
  • In essence I was using the basic JSON Java library from json.org, which is errr... basic. Brian in a roundabout way has pointed me to Gson as a better alternative for what I want to do (recreate classes easily from JSON strings). – Matt Stevens Feb 18 '13 at 20:09

1 Answers1

2

An enum in Java is a class, and the compiler adds a static valueOf(String name) method. So if you have:

enum MyEnum  { 
      ONE(1.0), TWO(2.0), THREE(3.0); 

      private double myDouble; 

      MyEnum(double d) {  
          myDouble = d;
      }

      public double getDouble() {
          return myDouble;
      }
}

You can say:

MyEnum e = MyEnum.valueOf("ONE");
assert(e.equals(MyEnum.ONE));
System.out.println(e.getDouble());

The more popular JSON parsers for Java handle enums just fine. Here's an example with Gson:

public class App
{

    public static void main(String[] args) 
    {
        // Array containing your enum constants
        String json = "[\"ONE\",\"TWO\",\"THREE\"]";

        Type t = new TypeToken<Collection<MyEnum>>(){}.getType();
        Collection<MyEnum> c = new Gson().fromJson(json, t);

        for (MyEnum me : c)
        {
            System.out.println(me);
            switch(me)
            {
                case ONE:
                    System.out.println("This is equal to MyEnum.ONE");
                    break;
                case TWO:
                    System.out.println("This is equal to MyEnum.TWO");
                    break;
                case THREE:
                    System.out.println("This is equal to MyEnum.THREE");
                    break;
            }
            System.out.println(me.getDouble());

        }
    }    
}

Output:

ONE
This is equal to MyEnum.ONE
1.0
TWO
This is equal to MyEnum.TWO
2.0
THREE
This is equal to MyEnum.THREE
3.0

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
  • Fixed the big red banner thing (I had to edit my post earlier as I could not comment on your post). Thanks for your reply, but it doesn't provide me with the enum, just the constants, admittedly in a collection which is quite a good idea. My enums also hold methods and need to be used in other classes as enums. This way would require a lot of re-writing. – Matt Stevens Feb 18 '13 at 08:40
  • PS. I'm very aware I could be looking for a non-existant answer. I'm picking I may need to do a major re-write and turn the enums into classes :( – Matt Stevens Feb 18 '13 at 08:51
  • 1
    Huh? I'm not even sure what you're talking about - I think you many not understand how enums work in Java? I demonstrated in the first example in my answer that you do indeed have your enum *object*. There's no such thing as "just the constants". – Brian Roach Feb 18 '13 at 17:08
  • I didn't bother looking at Gson as "Any of the JSON parsers for Java handle enums just fine." It would seem the one from JSON.org doesn't. I was quite surprised when I tracked down the TypeToken class and found the first stated goal of Gson is to enable doing exactly what I want (& by implication some other parsers don't). In a nutshell, I'll take your advice as a roundabout way of saying "go look at Gson". A very genuine thanks for the pointer, I should be ok from here. – Matt Stevens Feb 18 '13 at 19:47
  • @MattStevens - I haven't used that in ages but I'm surprised it doesn't, sorry; I'll edit. I know Jackson can as well (though it's a bit more clunky IIRC). – Brian Roach Feb 18 '13 at 20:11
  • maybe it does, at this point though I like what I'm reading in the Gson user guide. After a day of bashing my head against a brick wall, I'm just very pleased to be moving forward again :) cheers! – Matt Stevens Feb 18 '13 at 20:22