可以重写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之前只写出数据可能会更容易。

07-24 18:25