要从特定的序列化格式中抽象,我想要定义以下内容:
public interface TransportCodec {
void write(OutputStream out, Object obj) throws IOException;
Object read(InputStream in) throws IOException;
}
默认实现只使用Java对象序列化:
public void write(OutputStream out, Object obj) throws IOException {
ObjectOutputStream oout = new ObjectOutputStream(out);
oout.writeObject(obj);
oout.flush();
}
显然缺少oout.close()
,但出于某种原因:我希望能够通过对write
的独立调用将多个对象写入同一个流中。查看ObjectOutputStream
(jdk 1.8)的源代码,oout.close()
关闭基础流,但也清除属于ObjectOutputStream
的数据结构。但是,由于我将oout
保留在垃圾收集器中,因此我不会因为没有关闭流而产生问题。
除了未来JDK确实需要oout.close()
的风险之外,还有两个问题:
ObjectOutputStream
时,我在当前的JDK中松了什么。ByteArrayOutputStream
,然后将字节复制到out
,即可关闭oout
。还有更好的选择吗?答案 0 :(得分:0)
分成两个接口,使实现类“拥有”底层流。
优点:
基础存储不再仅限于OutputStream
/ InputStream
。
通过使两个接口扩展Closeable
,现在可以在try-with-resources块中使用它们。
来电者只需携带一个参考(例如TransportEncoder
),并且不再需要携带该流(例如OutputStream
)。
public interface TransportEncoder extends Closeable {
void write(Object obj) throws IOException;
}
public interface TransportDecoder extends Closeable {
Object read() throws IOException;
}
public final class ObjectStreamEncoder implements TransportEncoder {
private final ObjectOutputStream stream;
public ObjectStreamEncoder(OutputStream out) throws IOException {
this.stream = new ObjectOutputStream(out);
}
@Override
public void write(Object obj) throws IOException {
this.stream.writeObject(obj);
}
@Override
public void close() throws IOException {
this.stream.close();
}
}
public final class ObjectStreamDecoder implements TransportDecoder {
private final ObjectInputStream stream;
public ObjectStreamDecoder(InputStream in) throws IOException {
this.stream = new ObjectInputStream(in);
}
@Override
public Object read() throws IOException {
try {
return this.stream.readObject();
} catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(e.getMessage());
}
}
@Override
public void close() throws IOException {
this.stream.close();
}
}