views:

379

answers:

7

I want to override toString() for my enum, Color. However, I can't figure out how to get the value of an instance of Color inside the Color enum. Is there a way to do this in Java?

Example:

public enum Color {
    RED,
    GREEN,
    BLUE,
    ...

    public String toString() {
        // return "R" for RED, "G", for GREEN, etc.
    }
}
A: 

Java does this for you by default, it returns the .name() in .toString(), you only need to override toString() if you want something DIFFERENT from the name. The interesting methods are .name() and .ordinal() and .valueOf().

To do what you want you would do

.toString(this.name().substring(1));

What you might want to do instead is add an attribute called abbreviation and add it to the constructor, add a getAbbreviation() and use that instead of .toString()

fuzzy lollipop
Or better still, look up the string to display from a bundle for the cases where the first char of the enum name is not that for the locale teh app is running in.
vickirk
that is a good idea to make the code locale aware and internationalizable
fuzzy lollipop
+14  A: 
public enum Color {
    RED("R"),
    GREEN("G"),
    BLUE("B");

    private final String str;
    private Color(String s){
        str = s;
    }
    public String toString() {
        return str;
    }
}

You can use constructors for Enums. I haven't tested the syntax, but this is the idea.

Erkan Haspulat
I'd suggest adding a `final` and a couple of `private`s. Oh, and a semicolon.
Tom Hawtin - tackline
Thanks Tom, I've edited accordingly..
Erkan Haspulat
Forgive my question if it's a stupid one but shouldn't you use "@Override" before your toString method ?
Andy M
It's not an obligation, @Override is used by Javadoc. It's not a part of Java syntax.
Erkan Haspulat
@Erkan: @Override is not used by javadoc, javadoc can figure that out a method is overriden, it is there for the compiler.
vickirk
Thanks for the heads up, learning is cool :)
Erkan Haspulat
Yeah, @Override is good for those cases where you accidentally spell the method name wrong, or more likely in some cases, get the argument types wrong and aren't really overriding what you think you are. The compiler will yell at you.
PSpeed
+3  A: 

Enum.name() - who'd of thunk it?

However, in most cases it makes more sense to keep any extra information in an instance variable that is set int the constructor.

Michael Borgwardt
+1  A: 

Use super and String.substring():

public enum Color
{
    RED,
    GREEN,
    BLUE;

    public String toString()
    {
        return "The color is " + super.toString().substring(0, 1);
    }
}
mipadi
where super.toString() is really just calling the name() method that Michael Borgwardt mentioned in his answer.
MatrixFrog
A: 

Hey,

I've found something like this (not tested tho):

public enum Color {
RED{
public String toString() {
    return "this is red";
}
},
GREEN{
public String toString() {
    return "this is green";
}
},
...   

}

Hope it helps a bit !

Andy M
See Erkan H's answer for the right way to go about this sort of thing.
Mike Daniels
Oh yeah, I've seen it after I wrote this one ;) Thanks for the comment !
Andy M
@Mike: Any particular reason this is a bad idea? It seems the closest to what I actually want to do--I don't want to need to use constructors in the code that uses this enum.
Matthew
And with my solution, you don't have to use an intermediate var in the enum... Of course, it has the drawback of duplicating the code and make it bad to read... It's an interesting question !
Andy M
But if you had more than 3 elements in your enum, the code would become difficult to read I beleive. Method declaration of *toString()* gets rewritten so many times. It gets the job done, but I prefer my way..
Erkan Haspulat
you don't use constructors in code that uses enums, the constructors are private by default, btw this is a really bad way to do what you want
fuzzy lollipop
And if you really do not want to have local attribute and make changes to the contructor, you can just use @fuzzy lolipop's solution.
DJ
Ok I see, thanks for the comments guys !
Andy M
This method will also make each constant its own inner subclass of you Color type, splitting the enum into N+1 .class files. Probably not a problem, but something to be aware of.
ILMTitan
+3  A: 

You can also switch on the type of this, for example:

public enum Foo { 
  A, B, C, D 
  ; 
  @Override 
  public String toString() { 
    switch (this) { 
      case A: return "AYE"; 
      case B: return "BEE"; 
      case C: return "SEE"; 
      case D: return "DEE"; 
      default: throw new IllegalStateException(); 
    } 
  } 
} 
maerics
The downvotes make me think this probably isn't possible, but it would be ideal for what I want to do.
Matthew
No, you can do a switch on an enum, it was probably down voted because there are better ways, I would do something like Chinmay's solution. It's a shame it is possible to down vote without commenting.
vickirk
It compiles and works fine, not sure why it was down voted. In fact, the question asks "how to get the value" of an enum instance, which this answer describes...
maerics
This answer is much the same as @Andy M's answer but his uses the OO-fashionable polymorphic function and yours uses the much-hated switch statement. You have to be careful using switch on SO: it's a down-vote magnet.
Adrian Pronk
I returned it to '0' with my own up-vote. It answers the exact question posed even if this isn't the best way to achieve the meta-goal. For some other problem that actually does maybe require grabbing the enum instance it is important to remember that it's just an object like anything else and 'this' works.
PSpeed