java.lang.ClassCastException:java.util.HashSet无法强制转换为Custom Class

时间:2016-06-20 07:33:28

标签: java

FATAL EXCEPTION: AsyncTask #2
Process: my.app, PID: 15441
java.lang.ClassCastException: java.util.HashSet cannot be cast to my.app.ChatNotificationHashSet
at my.app.UserHandler.getChatNotificationMessage(UserHandler.java:127)
at my.app.NotificationUtil.getChatTitle(NotificationUtil.java:100)
at my.app.NotificationUtil.showChat(NotificationUtil.java:71)
at my.app.service.GCMListenerService.onMessageReceived(GCMListenerService.java:47)
at com.google.android.gms.gcm.GcmListenerService.zzq(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService.zzp(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService.zzo(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService.zza(Unknown Source)
at com.google.android.gms.gcm.GcmListenerService$1.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)

ChatNotificationHashSet

public class ChatNotificationHashSet<E> extends LinkedHashSet<String> {

    @Override
    public String toString() {
        // ...
    }
}

UserHandler(发生异常的地方)

public ChatNotificationHashSet<String> getChatNotificationMessage() {
        return (ChatNotificationHashSet<String>) pref.getStringSet(CHAT_NOTIFICATION_MESSAGE, null); // <- Exception occurs here
    }

    public void setChatNotificationMessage(ChatNotificationHashSet<String> messages) {
        SharedPreferences.Editor editor = pref.edit();
        editor.putStringSet(CHAT_NOTIFICATION_MESSAGE, messages);
        editor.commit();
    }

这怎么可能发生?在将null投射到ChatNotificationHashSet<String>时,不应该出现任何问题,对吗?我无法想到任何其他问题。

5 个答案:

答案 0 :(得分:3)

Set返回的getStringSet()不一定与传递给SharedPreferences.Editor.putStringSet()方法的Set相同。它通常取决于内部实施。我假设它将数据序列化并将其放入一些存储中并在检索时反序列化。

如果您需要特定的结构,可能最好实现一些包装器,它可以读取构造函数中的所有设置,也可以根据需要从基础{{1}}检索设置。

答案 1 :(得分:1)

pref.getStringSet()会返回HashSet而非您的课程,即使它在保存时可以将您的课程设为HashSet

答案 2 :(得分:1)

将值简单地复制到现有的HashSet中。您的收藏只是该副本的来源。

参考这个答案的评论: https://stackoverflow.com/a/13446387/1364747

  

用于修改SharedPreferences对象中的值的接口。所有   您在编辑器中所做的更改是批处理的,而不是复制回到   原始SharedPreferences直到你调用commit()或apply()   资料来源:SharedPreferences.Editor

仅在将提交更改复制到原始SharedPreferences之后。

答案 3 :(得分:0)

您的计划中出现此行

 return (ChatNotificationHashSet<String>) pref.getStringSet(CHAT_NOTIFICATION_MESSAGE, null); // <- Exception occurs here

因为你的ChatNotificationHashSet类是Strict-Type Argument(简单地说是泛型支持)。因此,此类已启用Type-Safety

此处getStringSet方法返回java.util.HashSet<String>类型的对象,该类型不是ChatNotificationHashSet<String>的类型。

因此,如您在代码中所见,将HashSet<String>类型对象转换为ChatNotificationHashSet<String>将容易ClassCastException

答案 4 :(得分:-1)

谢谢你们。我选择将列表保存为一个简单的JSON字符串,工作正常。