简体   繁体   中英

Enum, private final String odd behaviour

I have experienced an odd behaviour. Mainly, if I declare longName and iconPath as private final String, sometimes it happens that these fields values are broken, they have other value than expected. But if I change the variable type to private final Pair<String, String> data; it works fine, ArrayList also does the job. What could be the reason? I guess the String variable, which is immutable because of final term (although, somehow it does change its value).

package package.enums;
import package.MessageUtils;
public enum QuestionType {
    SIMPLE (
            MessageUtils.getBundle("survey.question.type.SIMPLE"),
            "/resources/images/question_default.png"
    ),
    COMPLEX (
            MessageUtils.getBundle("survey.question.type.COMPLEX"),
            "/resources/images/question_default.png"
    )
    // etcetera
    ;

    private final String longName;
    private final String iconPath;
    private QuestionType(String longName, String iconPath) {
        this.longName = longName;
        this.iconPath = iconPath;
    }
    public String getLongName() {
        return longName;
    }
    public String getIconPath() {
        return iconPath;
    }
}

This looks to me like a "cannot possibly happen" scenario.

The only semi-plausible explanation for a final not being initialized correctly is a threading related problem. However:

  • String values are definitely immutable and thread-safe,
  • there are strong guarantees that final fields are thread-safe, and
  • this code will be executed as part of the class initialization for the enum , and there are guarantees about that too.

In short: it CANNOT be a threading issue in the code you have shown us.

This leaves me with bizarre explanations like:

  • something is using nasty reflection to modify the strings,
  • something is using nasty reflection to modify the final fields, or
  • you are not running the code that you think you are; eg a build problem or there is some kind of out-of-control "bytecode engineering" going on.

Or ... MessageUtils.getBundle is returning the wrong string, under some circumstances that are yet to be determined.


This code might be a little bit misleading, I cannot just post the whole code of the app.

Or ... your real code is different to this code in some significant way. Please provide a Simple Self Contained Complete Example (SSCCE), or we are unlikely to be able to identify the real problem.

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