无法使可比较的实现 class、可序列化
Unable to make a comparable implemented class, serializable
我正在尝试将整个 TreeMap 对象保存到一个文件中,然后再次将其作为 TreeMap 加载回来。
treeMap 的键是一个对象,其class 实现了可比较的接口。虽然我实现了 Serializable 接口,但我无法将对象保存到文件中。
//This class object is used as key in the TreeMap
public class FourTuple<K1,K2,K3,K4> implements Comparable<FourTuple>, java.io.Serializable {
public final K1 rk;
public final K2 cf;
public final K3 cn;
public final K4 timestamp;
public FourTuple(K1 rk, K2 cf, K3 cn, K4 timestamp) {
this.rk=rk;
this.cf=cf;
this.cn=cn;
this.timestamp=timestamp;
}
public boolean equals(FourTuple ft) {
return ((this.rk==ft.rk)&&this.cf==ft.cf && this.cn==ft.cn && this.timestamp==ft.timestamp);
}
public int compareTo( FourTuple ft) {
if(this.rk==ft.rk) {
return this.timestamp.toString().compareTo(ft.timestamp.toString());
}
else
return this.rk.toString().compareTo(ft.rk.toString());
}
public String toString() {
return (rk + "=>" + cf + "=>" + cn + "=>" + timestamp);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cf == null) ? 0 : cf.hashCode());
result = prime * result + ((cn == null) ? 0 : cn.hashCode());
result = prime * result + ((rk == null) ? 0 : rk.hashCode());
result = prime * result + ((timestamp == null) ? 0 : timestamp.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FourTuple other = (FourTuple) obj;
if (cf == null) {
if (other.cf != null)
return false;
} else if (!cf.equals(other.cf))
return false;
if (cn == null) {
if (other.cn != null)
return false;
} else if (!cn.equals(other.cn))
return false;
if (rk == null) {
if (other.rk != null)
return false;
} else if (!rk.equals(other.rk))
return false;
if (timestamp == null) {
if (other.timestamp != null)
return false;
} else if (!timestamp.equals(other.timestamp))
return false;
return true;
}
}
获取错误日志如下图。 FourTuple Class(在 hbaseTest 项目中)不可序列化。
Exception in thread "main" java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: hbasetest.FourTuple
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1577)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at java.util.TreeMap.buildFromSorted(TreeMap.java:2567)
at java.util.TreeMap.buildFromSorted(TreeMap.java:2508)
at java.util.TreeMap.readObject(TreeMap.java:2454)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1170)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2178)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2287)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2211)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at hbasetest.DB.load(DB.java:83)
at hbasetest.DB.commit(DB.java:64)
at hbasetest.Driver.main(Driver.java:23)
Caused by: java.io.NotSerializableException: hbasetest.FourTuple
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at java.util.TreeMap.writeObject(TreeMap.java:2437)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1140)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at hbasetest.DB.save(DB.java:77)
at hbasetest.DB.commit(DB.java:63)
... 1 more
根据 Comparable 文档 class,默认情况下不是可序列化的。但是看了社区的其他帖子后,我尝试按照上面的方式实现。你能指出我在哪里犯了错误吗?
为了参考发布下面保存和检索对象的代码
public static void save(Object obj, File file) throws Exception{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file, true));
oos.writeObject(obj);
oos.flush();
oos.close();
}
public static Object load(File file) throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
Object result = ois.readObject();
ois.close();
return result;
}
如果你想要一个 FourTuple<K1,K2,K3,K4>
的可序列化实例:
- class
FourTuple
必须是可序列化的 => 没关系
- 所有属性 K1、K2、K3、K4 也必须是可序列化的 => 这里不保证
更改定义以进行编译器检查:
FourTuple <
K1 extends Serializable,
K2 extends Serializable,
K3 extends Serializable,
K4 extends Serializable
> implements Comparable<FourTuple>, Serializable
看到这个 raw-type
变化:
public boolean equals(FourTuple ft)
...
public int compareTo( FourTuple ft)
...
FourTuple other = (FourTuple) obj;
作者:
public boolean equals(FourTuple<K1,K2,K3,K4> ft)
...
public int compareTo( FourTuple<K1,K2,K3,K4> ft)
...
FourTuple<K1,K2,K3,K4> other = (FourTuple<>) obj;
我正在尝试将整个 TreeMap 对象保存到一个文件中,然后再次将其作为 TreeMap 加载回来。
treeMap 的键是一个对象,其class 实现了可比较的接口。虽然我实现了 Serializable 接口,但我无法将对象保存到文件中。
//This class object is used as key in the TreeMap
public class FourTuple<K1,K2,K3,K4> implements Comparable<FourTuple>, java.io.Serializable {
public final K1 rk;
public final K2 cf;
public final K3 cn;
public final K4 timestamp;
public FourTuple(K1 rk, K2 cf, K3 cn, K4 timestamp) {
this.rk=rk;
this.cf=cf;
this.cn=cn;
this.timestamp=timestamp;
}
public boolean equals(FourTuple ft) {
return ((this.rk==ft.rk)&&this.cf==ft.cf && this.cn==ft.cn && this.timestamp==ft.timestamp);
}
public int compareTo( FourTuple ft) {
if(this.rk==ft.rk) {
return this.timestamp.toString().compareTo(ft.timestamp.toString());
}
else
return this.rk.toString().compareTo(ft.rk.toString());
}
public String toString() {
return (rk + "=>" + cf + "=>" + cn + "=>" + timestamp);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cf == null) ? 0 : cf.hashCode());
result = prime * result + ((cn == null) ? 0 : cn.hashCode());
result = prime * result + ((rk == null) ? 0 : rk.hashCode());
result = prime * result + ((timestamp == null) ? 0 : timestamp.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FourTuple other = (FourTuple) obj;
if (cf == null) {
if (other.cf != null)
return false;
} else if (!cf.equals(other.cf))
return false;
if (cn == null) {
if (other.cn != null)
return false;
} else if (!cn.equals(other.cn))
return false;
if (rk == null) {
if (other.rk != null)
return false;
} else if (!rk.equals(other.rk))
return false;
if (timestamp == null) {
if (other.timestamp != null)
return false;
} else if (!timestamp.equals(other.timestamp))
return false;
return true;
}
}
获取错误日志如下图。 FourTuple Class(在 hbaseTest 项目中)不可序列化。
Exception in thread "main" java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: hbasetest.FourTuple
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1577)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at java.util.TreeMap.buildFromSorted(TreeMap.java:2567)
at java.util.TreeMap.buildFromSorted(TreeMap.java:2508)
at java.util.TreeMap.readObject(TreeMap.java:2454)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1170)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2178)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2287)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2211)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2069)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431)
at hbasetest.DB.load(DB.java:83)
at hbasetest.DB.commit(DB.java:64)
at hbasetest.Driver.main(Driver.java:23)
Caused by: java.io.NotSerializableException: hbasetest.FourTuple
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at java.util.TreeMap.writeObject(TreeMap.java:2437)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1140)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1496)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
at hbasetest.DB.save(DB.java:77)
at hbasetest.DB.commit(DB.java:63)
... 1 more
根据 Comparable 文档 class,默认情况下不是可序列化的。但是看了社区的其他帖子后,我尝试按照上面的方式实现。你能指出我在哪里犯了错误吗?
为了参考发布下面保存和检索对象的代码
public static void save(Object obj, File file) throws Exception{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file, true));
oos.writeObject(obj);
oos.flush();
oos.close();
}
public static Object load(File file) throws Exception{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
Object result = ois.readObject();
ois.close();
return result;
}
如果你想要一个 FourTuple<K1,K2,K3,K4>
的可序列化实例:
- class
FourTuple
必须是可序列化的 => 没关系 - 所有属性 K1、K2、K3、K4 也必须是可序列化的 => 这里不保证
更改定义以进行编译器检查:
FourTuple <
K1 extends Serializable,
K2 extends Serializable,
K3 extends Serializable,
K4 extends Serializable
> implements Comparable<FourTuple>, Serializable
看到这个 raw-type
变化:
public boolean equals(FourTuple ft)
...
public int compareTo( FourTuple ft)
...
FourTuple other = (FourTuple) obj;
作者:
public boolean equals(FourTuple<K1,K2,K3,K4> ft)
...
public int compareTo( FourTuple<K1,K2,K3,K4> ft)
...
FourTuple<K1,K2,K3,K4> other = (FourTuple<>) obj;