将Object转换为List <string> </string>时出现ClassCastException

时间:2013-04-24 16:47:45

标签: java android classcastexception

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

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

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

以下获取共享偏好的完整方法。谢谢你的建议!

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 个答案:

答案 0 :(得分:4)

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

return ERROR;

声明为String

final String ERROR = "ERROR";

此外,这可能会返回String

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

可能相关:

if (json != "") {

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

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

甚至是这样:

if (json.isEmpty()) {

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

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

答案 1 :(得分:1)

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

如果json为空,则返回ERROR witch是一个String。如果您尝试强制转换为List,则会导致异常。

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

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