可以重写ObjectOutputStream.writeStreamHeader()
方法,以在数据头之前或之后添加数据。但是,如果该数据基于传递给派生类的构造函数的参数,例如:
public class MyObjectOutputStream extends ObjectOutputStream {
public MyObjectOutputStream( int myData, OutputStream out ) throws IOException {
super( out );
m_myData = myData;
}
protected void writeStreamHeader() throws IOException {
write( m_myData ); // WRONG: m_myData not initialized yet
super.writeStreamHeader();
}
private final int m_myData;
}
它不起作用,因为在初始化
super()
之前调用了m_myData
,并且super()
调用writeStreamHeader()
。我认为可以解决此问题的唯一方法是使用ThreadLocal
:public class MyObjectOutputStream extends ObjectOutputStream {
public MyObjectOutputStream( int myData, OutputStream out ) throws IOException {
super( thunk( myData, out ) );
}
protected void writeStreamHeader() throws IOException {
write( m_myData.get().intValue() );
super.writeStreamHeader();
}
private static OutputStream thunk( int myData, OutputStream out ) {
m_myData.set( myData );
return out;
}
private static final ThreadLocal<Integer> m_myData = new ThreadLocal<Integer>();
}
这似乎可行,但是有没有更好的方法(不太笨拙)?
最佳答案
有一种解决此类问题的通用方法。使类和内部类在外部范围内引用变量。 (注意,这仅适用于-target 1.4
或greter,这是javac当前版本中的默认设置。使用-target 1.3
,您将获得一个NPE。)
public static ObjectOutputStream newInstance(
final int myData, final OutputStream out
) throws IOException {
return new ObjectOutputStream(out) {
@Override
protected void writeStreamHeader() throws IOException {
write(myData);
super.writeStreamHeader();
}
};
}
但是,在构造
ObjectOuputStream
之前只写出数据可能会更容易。