Metoda ObjectOutputStream.writeStreamHeader()
może zostać nadpisana, aby przedłużyć lub dołączyć dane do nagłówka. Jednak, jeśli dane są oparte na argument przekazany do konstruktora klasy pochodnej, niczym:Jak przesłonić 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;
}
to nie działa, ponieważ super()
jest wywoływana przed m_myData
jest inicjowany i super()
rozmowy writeStreamHeader()
. Jedynym sposobem mogę myśleć, aby obejść ten jest za pomocą ThreadLocal
jak:
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>();
}
To wydaje się działać, ale jest tam lepsze (mniej niezgrabne) sposób?
Podoba mi się to rozwiązanie, ponieważ przesłania on writeStreamHeader() "zgodnie z przeznaczeniem", a nagłówek jest zapisywany w "właściwym czasie" i nie zawiera żadnych założeń dotyczących tego, kiedy metoda jest wywoływana przez konstruktor klasy podstawowej. Jako taki jest "odporny na przyszłość". –
Schludny. Podobno zewnętrzny zakres zostanie zainicjowany przed konstruktorem superklasy. – Thilo
Tak, specyfikacja VM musiała zostać zmieniona, aby umożliwić tego rodzaju rzeczy. Nadal może się skomplikować - ostatni raz sprawdziłem przykład w JLS nie działał z javakiem czasu. –