我試圖序列化類InstitutionResultView的一些對象,其基本包裝器guava's TreeMultimap:序列化校書郎例如
import java.io.Serializable;
import java.text.Collator;
import java.util.Comparator;
import com.google.common.base.Function;
import com.google.common.base.Objects;
import com.google.common.collect.Maps.EntryTransformer;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Ordering;
import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
public class InstitutionResultView implements Serializable {
private static final long serialVersionUID = -8110992296090587657L;
private final SortedSetMultimap<String, Institution> nameToInstitutionsMapping = TreeMultimap.create(
Ordering.from(StringComparators.AS_IS), // insertion order
Ordering.natural() // <----- this works when serializing object
// Ordering.from(Collator.getInstance()) // <----- when used instead previous line gives an exception when serializing
.nullsFirst().onResultOf(StringInstitutionFunctions.BY_NAME) // sort by name
.compound(
Ordering.natural().nullsFirst().onResultOf(IntegerInstitutionFunctions.BY_ID) // sort by id
));
public SortedSetMultimap<String, Institution> institutions() {
return nameToInstitutionsMapping;
}
public void setInstitutions(final Multimap<String, Institution> institutions) {
this.nameToInstitutionsMapping.clear();
this.nameToInstitutionsMapping.putAll(institutions);
}
@Override
public String toString() {
return Objects.toStringHelper(this)
.add("nameToInstitutionsMapping", Multimaps.transformEntries(nameToInstitutionsMapping, EntryTransformers.TO_NAME_WITH_CATEGORY))
.toString();
}
序列化過程中,我得到異常:
java.io.NotSerializableException:JAVA。 text.RuleBasedCollator java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164) at
...
com.google.common.collect.TreeMultimap.writeObject(TreeMultimap.java:180)
...
我發現this bug from Sun's bug database這非常類似的事例涵蓋礦山,但它並不指向任何決議。我嘗試添加瞬態校書郎實例字段:
private transient Collator collatorInstance = Collator.getInstance();
,並用它作爲Ordering.from(collatorInstance)
但仍無法正常工作。
我很高興如果有人能給我一些想法該怎麼做來解決這個問題。
編輯 - 這是對我工作(感謝@Puce他的回答):
class CollatorWrapper implements Comparator<String>, Serializable {
private static final long serialVersionUID = 1L;
private transient Collator collatorInstance;
public CollatorWrapper() {
super();
initCollatorInstance();
}
@Override
public int compare(final String o1, final String o2) {
return collatorInstance.compare(o1, o2);
}
private void initCollatorInstance() {
collatorInstance = Collator.getInstance();
}
private void writeObject(final java.io.ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
private void readObject(final java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initCollatorInstance();
}
}
不過請注意,如果你不存儲區域設置,你會得到一個不同的行爲,如果JVM序列化對象和jvm反序列化對象具有不同的默認語言環境。也許這就是你想要的,但是,我只是想指出。 – Puce
我知道這一點,我已經使用Locale參數實現了CollatorWrapper,但在這裏我只想顯示這個問題的解決方案的本質:) – Xaerxess
我不積極,但我認爲你可以通過聲明 來避免「initCollatorInstance」的尷尬 專用瞬態Collator collatorInstance = Collator.getInstance() 直接。 –