-2

我正在开发 Android 应用程序,并且我已经实现了一个类,用于使用共享首选项进行所有处理。这个类拥有一个获取首选项的通用方法,它是通用的,它根据参数返回不同类型的数据类型。我在共享首选项中存储和检索的数据类型是整数、字符串、布尔值和列表(使用 JSON 对字符串进行序列化/反序列化)。好吧,一切都很好,我可以通过这种方式成功地从共享首选项中获取 int、string 和 boolean,但不是 List,因为我得到了:

java.lang.ClassCastException: java.lang.String cannot be cast to java.util.List

我忘了告诉该方法被声明为返回一个对象,并且当它被调用时,返回的值被类型转换为正确的类型。无论如何,我不明白为什么它说不能转换字符串,它甚至不返回字符串?这是一种正确的方法吗?我的意思是返回一个对象然后强制转换它是完全正确的。

获取以下共享首选项的完整方法。感谢您的任何建议!

public Object getPrefs(String sharedPreferences, String key, int type,
        Context context, Object defaultObject) {
    // A String indicating an error occurred while retrieving shared
    // preferences
    final String ERROR = "ERROR";

    // Set shared preferences from context
    sharedPref = context.getSharedPreferences(sharedPreferences,
            Context.MODE_PRIVATE);

    switch (type) {
    case (0): // <-- Integer
        // Check that defaultObject is of correct instance else collect
        // "hardcoded" default value of 0
        if (defaultObject instanceof Integer) {
            this.logger.logCatTxt(
                    this.logger.getINFO(),
                    this.LOG_TAG + ":getPrefs()",
                    "Integer with value"
                            + Integer.toString(sharedPref.getInt(key,
                                    (Integer) defaultObject))
                            + " retrieved from shared preferences: "
                            + sharedPreferences + ", with key: " + key
                            + ", type: " + Integer.toString(type)
                            + ", context: " + context.toString()
                            + " and default value: "
                            + Integer.toString((Integer) defaultObject));
            return sharedPref.getInt(key, (Integer) defaultObject);
        } else {
            this.logger
                    .logCatTxt(
                            this.logger.getERROR(),
                            this.LOG_TAG + ":getPrefs()",
                            "Default value couldn't be set because of instance mismatch, hardcoded default value of 0 is used. However Integer with value"
                                    + Integer.toString(sharedPref.getInt(
                                            key, 0))
                                    + " retrieved from shared preferences: "
                                    + sharedPreferences
                                    + ", with key: "
                                    + key
                                    + ", type: "
                                    + Integer.toString(type)
                                    + ", context: "
                                    + context.toString()
                                    + " and default value: "
                                    + Integer
                                            .toString((Integer) defaultObject));
            return sharedPref.getInt(key, 0);
        }
    case (1): // <-- String
        // Check that defaultObject is of correct instance else collect
        // "hardcoded" default value of ""
        if (defaultObject instanceof String) {
            this.logger.logCatTxt(
                    this.logger.getINFO(),
                    this.LOG_TAG + ":getPrefs()",
                    "String with value"
                            + sharedPref.getString(key,
                                    (String) defaultObject)
                            + " retrieved from shared preferences: "
                            + sharedPreferences + ", with key: " + key
                            + ", type: " + Integer.toString(type)
                            + " and context: " + context.toString()
                            + " and default value: "
                            + (String) defaultObject);
            return sharedPref.getString(key, (String) defaultObject);
        } else {
            this.logger
                    .logCatTxt(
                            this.logger.getERROR(),
                            this.LOG_TAG + ":getPrefs()",
                            "Default value couldn't be set because of instance mismatch, hardcoded default value of \"\" is used. However String with value"
                                    + sharedPref.getString(key, "")
                                    + " retrieved from shared preferences: "
                                    + sharedPreferences
                                    + ", with key: "
                                    + key
                                    + ", type: "
                                    + Integer.toString(type)
                                    + " and context: " + context.toString());
            return sharedPref.getString(key, "");
        }
    case (2): // <-- Boolean
        // Check that defaultObject is of correct instance else collect
        // "hardcoded" default value of false
        if (defaultObject instanceof Boolean) {
            this.logger.logCatTxt(
                    this.logger.getINFO(),
                    this.LOG_TAG + ":getPrefs()",
                    "Boolean with value"
                            + sharedPref.getBoolean(key,
                                    (Boolean) defaultObject)
                            + " retrieved from shared preferences: "
                            + sharedPreferences + ", with key: " + key
                            + ", type: " + Integer.toString(type)
                            + " and context: " + context.toString()
                            + " and default value: "
                            + (Boolean) defaultObject);
            return sharedPref.getBoolean(key, (Boolean) defaultObject);
        } else {
            this.logger
                    .logCatTxt(
                            this.logger.getERROR(),
                            this.LOG_TAG + ":getPrefs()",
                            "Default value couldn't be set because of instance mismatch, hardcoded default value of false is used. However Boolean with value"
                                    + sharedPref.getBoolean(key, false)
                                    + " retrieved from shared preferences: "
                                    + sharedPreferences
                                    + ", with key: "
                                    + key
                                    + ", type: "
                                    + Integer.toString(type)
                                    + " and context: " + context.toString());
            return sharedPref.getBoolean(key, false);
        }
    case (3): // <-- List
        // Retrieve secondaryListenNumbers to json string and clear
        // secondaryListenNumbers List just to be sure that it's empty
        String json = sharedPref.getString(key, "");
        // List of Strings containing
        List<String> list = new ArrayList<String>();

        // If json string is not empty
        if (json != "") {
            try {
                // Create a JSONArray from json string and retrieve strings
                // from it and and them to secondaryListenNumbers List
                JSONArray a = new JSONArray(json);
                for (int i = 0; i < a.length(); i++) {
                    String secondaryListenNumber = a.optString(i);
                    list.add(secondaryListenNumber);
                }
                this.logger.logCatTxt(this.logger.getINFO(), this.LOG_TAG
                        + ":getPrefs()", "List<String> with value(s)" + json
                        + "   retrieved from shared preferences: "
                        + sharedPreferences + ", with key: " + key
                        + ", type: " + Integer.toString(type)
                        + " and context: " + context.toString());
                // Return the list
                return list;
            } catch (JSONException e) {
                e.printStackTrace();
                this.logger.logCatTxt(this.logger.getERROR(), this.LOG_TAG
                        + ":getPrefs()",
                        "Failed to retrieve List<String> from shared preferences: "
                                + sharedPreferences + ", with key: " + key
                                + ", type: " + Integer.toString(type)
                                + " and context: " + context.toString(), e);
            }
        }
        break;
    default:
        this.logger.logCatTxt(this.logger.getWARN(), this.LOG_TAG
                + ":getPrefs()",
                "Unsupported data type was givien as parameter. Shared preferences: "
                        + sharedPreferences + ", with key: " + key
                        + ", type: " + Integer.toString(type)
                        + " and context: " + context.toString());
    }

    // We should never reach this far but if we do an error has occurred and
    // we return the ERROR string
    return ERROR;
}
4

4 回答 4

5

是的,您的方法可以返回String

return ERROR;

它被声明为String.

final String ERROR = "ERROR";

此外,这可能会返回一个String

return sharedPref.getString(key, (String) defaultObject);

可能相关:

if (json != "") {

不要将字符串值与==or进行比较!=。使用String#equals,即

if (!json.equals("")) {

甚至这个:

if (json.isEmpty()) {

在 Java 中,String如果出现错误则返回错误并不是一个好的设计。

Exception如果有错误,最好抛出某种类型,并让调用方法捕获异常并处理错误。

于 2013-04-24T16:57:25.547 回答
1

您正在比较一个不等于运算符的字符串:if (json != "")您应该使用if (!"".equals(json)).

如果 json 为空,则返回 ERROR 女巫是一个字符串。如果您尝试强制转换为列表,则会导致异常。

于 2013-04-24T16:57:15.607 回答
1
java.lang.String cannot be cast to java.util.List

错误字符串说:您正在尝试将字符串转换为列表。使用调试器找到它。

于 2013-04-24T17:00:27.653 回答
1

如果返回类型为,则在转换为另一种类型时Object使用它是一个好主意。instanseof同样如前所述,不要返回错误字符串,最好抛出一个Exception

于 2013-04-24T17:01:23.457 回答