Phương thức ObjectOutputStream.writeStreamHeader()
có thể được ghi đè để thêm hoặc thêm dữ liệu vào tiêu đề. Tuy nhiên, nếu dữ liệu được dựa trên một cuộc tranh cãi được truyền cho constructor lớp được thừa kế của như:Làm thế nào để ghi đè lên 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;
}
nó không hoạt động vì super()
được gọi trước khi m_myData
được khởi tạo và super()
cuộc gọi writeStreamHeader()
. Cách duy nhất tôi có thể nghĩ đến việc xung quanh này là bằng cách sử dụng ThreadLocal
như:
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>();
}
Điều này dường như làm việc, nhưng là có một (ít phiền phức) cách tốt hơn?
Tôi thích giải pháp này vì nó ghi đè writeStreamHeader() "như dự định" và tiêu đề được viết vào "thời điểm thích hợp" và không đưa ra giả định về khi phương thức được gọi bởi hàm tạo lớp cơ sở. Như vậy, đó là "bằng chứng trong tương lai". –
Gọn gàng. Rõ ràng phạm vi bên ngoài được khởi tạo trước hàm tạo của lớp bậc trên. – Thilo
Vâng, thông số VM phải được thay đổi để cho phép điều đó. Nó vẫn có thể trở nên phức tạp - lần cuối tôi kiểm tra một ví dụ trong JLS đã không làm việc với javac của thời gian. –