简体   繁体   中英

Generic use of Enum.valueOf

I'm attempting to generalize saving of Enums to preferences.

To save an enum, I can use:

public static <T extends Enum<T>> void savePreference(final Context context, final String id, final T value) {
    SharedPreferences settings = context.getSharedPreferences(SESSION_TOKEN, Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = settings.edit();
    editor.putString(id, value.name());
    editor.apply();
}

I'm trying to do something along the following, which would allow me to read a preference into a generic enum:

public static <T extends Enum<T>> T getPreference(final Context context, final String id, final T defaultValue) {
    try {
        SharedPreferences settings = context.getSharedPreferences(SESSION_TOKEN, Context.MODE_PRIVATE);
        String name = settings.getString(id, null);
        return name != null ? Enum.valueOf(T, name) : defaultValue;
    } catch (Exception e) {
        Log.e("ERROR GETTING", e.toString());
        return defaultValue;
    }
}

But that gives me the error:

Error:(93, 48) error: cannot find symbol variable T

on the "Enum.valueOf(T, name)" expression.

I've also tried using T.valueOf(name) but that yields a parameter mismatch error.

I've been able to work around it by not using the generics and coding specific implementations, but that kind of defeats the purpose:

public static Constants.ButtonLocations getPreference(final Context context, final String id, final Constants.ButtonLocations defaultValue) {
    try {
        SharedPreferences settings = context.getSharedPreferences(SESSION_TOKEN, Context.MODE_PRIVATE);
        String name = settings.getString(id, null);
        return name != null ? Constants.ButtonLocations.valueOf(name) : defaultValue;
    } catch (Exception e) {
        Log.e("ERROR GETTING", e.toString());
        return defaultValue;
    }
}

How can I create the generic version of getPreference?

You can add a Class<T> parameter to your method

public static <T extends Enum<T>> T getPreference(final Context context, final String id, final Class<T> clazz, final T defaultValue)

Then you can use

Enum.valueOf(clazz, name)

Alternatively, if defaultValue is never going to be null , you can get rid of this extra parameter and use this default value to get the class.

Enum.valueOf(defaultValue.getDeclaringClass(), name)

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