David Berry
David Berry

Reputation: 41246

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?

Upvotes: 3

Views: 1836

Answers (1)

Paul Boddington
Paul Boddington

Reputation: 37655

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)

Upvotes: 7

Related Questions