如何覆盖ObjectOutputStream.writeStreamHeader()?

Pau*_*cas 5 java constructor objectoutputstream thread-local

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;
}
Run Code Online (Sandbox Code Playgroud)

它不起作用,因为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>();
}
Run Code Online (Sandbox Code Playgroud)

这似乎有效,但有更好(不那么笨重)的方式吗?

Tom*_*ine 3

有一个通用的方法可以解决此类问题。创建类和内部类,并在外部作用域中引用变量。(注意,这仅适用于-target 1.4或 grter,这是当前版本的 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();
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

但是,在构建ObjectOuputStream.