68

It seems to be possible in Java to write something like this:

 private enum TrafficLight {
  RED,
  GREEN;

  public String toString() {
   return //what should I return here if I want to return
                               //"abc" when red and "def" when green?
  }
 }

Now, I'd like to know if it possible to returnin the toString method "abc" when the enum's value is red and "def" when it's green. Also, is it possible to do like in C#, where you can do this?:

 private enum TrafficLight {
  RED = 0,
  GREEN = 15
  ...
 }

I've tried this but it but I'm getting compiler errors with it.

Thanks

devoured elysium
  • 101,373
  • 131
  • 340
  • 557

4 Answers4

120

You can do it as follows:

private enum TrafficLight {
   // using the constructor defined below
   RED("abc"),
   GREEN("def");

   // Member to hold the name
   private String string;

   // constructor to set the string
   TrafficLight(String name){string = name;}

   // the toString just returns the given name
   @Override
   public String toString() {
       return string;
   }
}

You can add as many methods and members as you like. I believe you can even add multiple constructors. All constructors must be private.

An enum in Java is basically a class that has a set number of instances.

ThomasW
  • 16,981
  • 4
  • 79
  • 106
jjnguy
  • 136,852
  • 53
  • 295
  • 323
  • 9
    This should be flagged as the correct answer. The chosen solution is not scalable at all. – Erica Kane Apr 13 '16 at 19:43
  • 1
    @EricaKane, which one is not scalable, the "toString with a switch" one? Why is it not scalable? It compiles to the `tableswitch` JVM instruction which means there is no "loop-if" over the switch cases - instead the case value is used to compute the next instruction offset. Also, considering that enums usually contain just a few values, scalability is rarely an issue. – Vsevolod Golovanov May 30 '16 at 11:51
  • 3
    @VsevolodGolovanov The "toString with a switch" is not scalable as you need to add a case for each member of the enum. On the other hand the proposed solution with the constructor is much more powerful as it is very easy to show a custom name, e.g. `TrafficLight(String name, int value) {this.value = value; string = name + "(" + value + ")";}` – nkatsar May 04 '17 at 14:33
  • Thank you @jjnguy for this answer together with comments. Each enumeration is an object where I can define a constructor. That constructor does the magic afterwards! This is where I racked my brains. – Vaclav Vlcek Jul 08 '22 at 23:25
94

Ans 1:

enum TrafficLight {
  RED,
  GREEN;

  @Override
  public String toString() {
    switch(this) {
      case RED: return "abc";
      case GREEN: return "def";
      default: throw new IllegalArgumentException();
    }
  }
}

Ans 2:

enum TrafficLight {
  RED(0),
  GREEN(15);

  int value;
  TrafficLight(int value) { this.value = value; }
}
missingfaktor
  • 90,905
  • 62
  • 285
  • 365
  • 3
    Can also override `toString` in each instance, although that adds to the number of classes. And probably isn't that clean, but good for related situations. – Tom Hawtin - tackline Mar 23 '10 at 04:50
23

Also if You need to get lowercase string value of enum ("red", "green") You can do it as follows:

private enum TrafficLight {
  RED,
  GREEN;

  @Override
  public String toString() {
   return super.toString().toLowerCase();
  }
}
user3054516
  • 331
  • 2
  • 2
7

I liked this approach for selective alternate toString() if it's useful for anyone out there :

private enum TrafficLight {
  RED,
  GREEN {
    @Override
    public String toString() {
        return "GREEN-ISH";
    }
  }
}
mud
  • 85
  • 1
  • 7