简体   繁体   中英

Java enum overriding toString()

I've never really made use of Java enum classes before for constant values, I've typically used the "public final" approach in the past. I've started using an enum now and I'm overriding the toString() method to return a different value than the enum name.

I have some JPA code in which I'm creating a TypedQuery with named parameters, one of which is a String representation of the enum value. If I merely set the parameter using Status.ACTIVE, I get the proper "A" value, but an exception is thrown because it's type is actually Status rather than String. It only works if I explicitly call the toString() method. I thought that simply overriding the toString() method would result in a String type being returned, no matter what the class type was.

This is the enum:

public enum Status {
    ACTIVE ("A"),
    PENDING ("P"),
    FINISHED ("F");

    private final String value;

    Status(String value) {
        this.value = value;
    }

    public String toString() {
        return value;
    }
};

This is the TypedQuery:

    TypedQuery<MechanicTimeEvent> query = entityManager().createQuery("SELECT o FROM MechanicTimeEvent o WHERE o.id.mechanicNumber = :mechanicNumber AND o.id.status = :status", MechanicTimeEvent.class);
    query.setParameter("mechanicNumber", mechanicNumber);
    query.setParameter("status", Status.ACTIVE.toString());
public enum Status {
    ACTIVE,
    PENDING,
    FINISHED;

    @Override
    public String toString() {
        String name = "";
        switch (ordinal()) {
        case 0:
            name = "A";
            break;
        case 1:
            name = "P";
            break;
        case 2:
            name = "F";
            break;
        default:
            name = "";
            break;
        }
        return name;
    }
};

If I understand your question correctly, You should do the enum mapping other way around. In this way states are stored as state and JPA would process the enum based on its name A,P, F).

public enum Status {
    A("ACTIVE"),
    P("PENDING"),
    F("FINISHED");

In this way you can just pass Status without invoking the toString() method to JPA. The .name() method on the ENUM will be invoked automatically to get the status code for persistence.

Is the field status of the MechanicTimeEvent bean an enum type? If not, I would suggest to change it to the enum type Status .

You can annotate it with @Enumerated(EnumType.STRING)

Furthermore I would suggest to remove the value part of your enum and just use the names like:

public enum Status {
   ACTIVE,
   PENDING,
   FINISHED;
}

This or you simply implement a getter for the value:

public String getValue()

And you call it in your code:

query.setParameter("status", Status.ACTIVE.getValue());

toString is just an ordinary method in Object that is explicitly called by some methods like PrintStream.println (remember System.out.println) or considered during concatenation using the + operator. Not every method needs to implement this behavior.

I'd suggest you use a more descriptive method name like getValue and call it explicitly instead of override toString

java.lang.Enum said clearly:
 /**
 * Returns the name of this enum constant, exactly as declared in its
 * enum declaration.
 * 
 * <b>Most programmers should use the {@link #toString} method in
 * preference to this one, as the toString method may return
 * a more user-friendly name.</b>  This method is designed primarily for
 * use in specialized situations where correctness depends on getting the
 * exact name, which will not vary from release to release.
 *
 * @return the name of this enum constant
 */
 public final String name()

just like the loft say ,you can use "name" method to get the name. also you can use toString() method.

of course it is just name of this enum constant.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM