tags:

views:

107

answers:

4
+4  Q: 

Java String enum

Hello,

what is the best way to have a enum type represent a set of strings eg

enum Strings{
   STRING_ONE("ONE"), STRING_TWO("TWO")
}

so i can use them as Strings?

Thanks

+5  A: 

Use its name() method:

public class Main {
    public static void main(String[] args) throws Exception {
        System.out.println(Strings.ONE.name());
    }
}

enum Strings {
    ONE, TWO, THREE
}

yields ONE.

Bart Kiers
Yeah, but `Strings.STRING_ONE.name()` yields "STRING_ONE", not "ONE". This simply isn't a good answer. You can't have any String that wouldn't be a valid Java identifier, etc.
Mark Peters
@Mark, true, it can't handle any character. If the OP just wants a single char, this solution is more straight forward than The Elite Gentleman suggestion. But indeed: if the range of characters exceeds the ones a valid Java identifier can have, this is a no-go. Good point.
Bart Kiers
It is very reasonable to have an internal naming convention for an enum that is different from what one would want to show with toString() (especially if a user sees the output), so I don't think this is quite what the OP was looking for.
Michael McGowan
+10  A: 

I don't know what you want to do, but this is how I actually translated your example code....

/**
 * 
 */
package test;

/**
 * @author The Elite Gentleman
 *
 */
public enum Strings {
    STRING_ONE("ONE"),
    STRING_TWO("TWO")
    ;
    /**
     * @param text
     */
    private Strings(final String text) {
        this.text = text;
    }

    private final String text;

    /* (non-Javadoc)
     * @see java.lang.Enum#toString()
     */
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return text;
    }
}

Alternatively, you can create a getter method for text.

You can now do Strings.STRING_ONE.toString();

The Elite Gentleman
I don't know if it is a compiler requirement, but `private String text` should be final.
Jonathan
@Jonathan, nope, mine compiled fine....
The Elite Gentleman
@Jonathan, if it were final, I think that you could not assing a value at the constructor. Could you?
Tomas Narros
@Tomás Narros Yes, you can still assign to it in the constructor, as long as you don't give it a value when you declare it final.
Jonathan
@The Elite Gentleman It would be bad if the value of an enum constant changed during runtime, so even if not required, `final` would be best.
Jonathan
@Jonathan: Thanks. This is something I've never used (always intialized final fields at declaration).
Tomas Narros
@Jonathan Thanks, I've included `final` on `text`.
The Elite Gentleman
+2  A: 

Either set the enum name to be the same as the string you want or, more generally,you can associate arbitrary attributes with your enum values:

enum Strings {
   STRING_ONE("ONE"), STRING_TWO("TWO");
   private String stringValue;
   Strings(String s) { stringValue = s; }
   public String toString() { return stringValue; }
   // further methods, attributes, etc.
}

It's important to have the constants at the top, and the methods/attributes at the bottom.

Adrian Smith
And also to have a **private** constructor.
The Elite Gentleman
enum constructors are private by default and require no access modifier. But that's a good point about access modifiers in general, I have updated my code to add them to the attribute and accessor.
Adrian Smith
And make `stringValue` final.
Steve Kuo
A: 

Depending on what you mean by "use them as Strings", you might not want to use an enum here. In most cases, the solution proposed by The Elite Gentleman will allow you to use them through their toString-methods, e.g. in System.out.println(STRING_ONE) or String s = "Hello "+STRING_TWO, but when you really need Strings (e.g. STRING_ONE.toLowerCase()), you might prefer defining them as constants:

public interface Strings{
  public static final String STRING_ONE = "ONE";
  public static final String STRING_TWO = "TWO";      
}
hd42
actually this is what i am trying to avoid...!
Rrackham
Actually, if they also want the `toLowerCase()` on my solution, they can go `Strings.STRING_TWO.toString().toLowerCase()`.
The Elite Gentleman
Sure, but that is not using them as strings as I interpreted it. As Rrackham doesn't seem to require that use, he of course should use the proposed enum solution.
hd42