Как переопределить ObjectOutputStream.writeStreamHeader ()?

m.str("");

, кажется, работает.

5
задан Paul J. Lucas 6 July 2009 в 07:29
поделиться

4 ответа

Существует общий способ решения такого рода проблем. Создайте класс и внутренний класс и укажите переменную во внешней области. (Обратите внимание, это работает только с -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 .

3
ответ дан 14 December 2019 в 19:22
поделиться

Как правило, вызывать неокончательные методы из конструктора ( именно по той причине, которую вы указали).

Можете ли вы добиться своей пользовательской сериализации без расширения ObjectOutputStream? Я думаю о составе потока. Например, вы можете добавить свой заголовок, записав его в базовый OutputStream до того, как это сделает ObjectOutputStream. Это, очевидно, нельзя сделать в подклассе ObjectOutputStream, но это легко сделать извне.

   out.write(myExtraHeader);
   ObjectOutputStream oos = new ObjectOutputStream(out);

Если хотите, вы можете красиво обернуть все это за интерфейсом ObjectOutput, как предложил Стю Томпсон в своем ответе, чтобы он может выглядеть снаружи почти как ObjectOutputStream.

Обновление:

Если посмотреть на JavaDocs и исходный код для ObjectOutputStream, есть второй (защищенный) конструктор, который не вызывает writeStreamHeader () .

Однако этот конструктор также не инициализирует другие внутренние структуры. Чтобы процитировать документы, так что он может выглядеть снаружи почти как ObjectOutputStream.

Обновление:

Если посмотреть на JavaDocs и исходный код для ObjectOutputStream, есть второй (защищенный) конструктор, который не вызывает writeStreamHeader () .

Однако этот конструктор также не инициализирует другие внутренние структуры. Чтобы процитировать документы, так что он может выглядеть снаружи почти как ObjectOutputStream.

Обновление:

Если посмотреть на JavaDocs и исходный код для ObjectOutputStream, есть второй (защищенный) конструктор, который не вызывает writeStreamHeader () .

Однако этот конструктор также не инициализирует другие внутренние структуры. Чтобы процитировать документы, он предназначен «для подклассов, которые полностью реализуют ObjectOutputStream. чтобы не выделять частные данные, которые используются только этой реализацией ObjectOutputStream ". В этом случае он также вызывает некоторые другие методы, такие как" writeObjectOverride ". Беспорядок ...

1
ответ дан 14 December 2019 в 19:22
поделиться

Не могли бы вы сделать это вот так. Игнорируйте вызов writeStreamHeader из суперконструктора и выполните его самостоятельно, когда вы инициализировали необходимое поле:

public class MyObjectOutputStream extends ObjectOutputStream {

private boolean initalized = false;
private final int m_myData;

protected MyObjectOutputStream(int myData, OutputStream out) throws IOException, SecurityException {
    super(out);
    m_myData = myData;
    initalized = true;
    writeStreamHeader();
}

protected void writeStreamHeader() throws IOException {

    if(!initalized){
        return;
    }

    write( m_myData );
    super.writeStreamHeader();
}
}

РЕДАКТИРОВАТЬ:

Или, как предлагает Тило , это можно было бы записать так:

public class MyObjectOutputStream extends ObjectOutputStream {

    private final int m_myData;

    protected MyObjectOutputStream(int myData, OutputStream out) throws IOException, SecurityException {
        super(out);
        m_myData = myData;
        write( m_myData );
        super.writeStreamHeader();
    }

    protected void writeStreamHeader() throws IOException {
        // work is done in the constructor
    }
}
1
ответ дан 14 December 2019 в 19:22
поделиться

Использовать композицию вместо наследования.

public class MyObjOutStream implements DataOutput, ObjectOutput, ObjectStreamConstants {
    //same interfaces that ObjectOutputStream implements

    private ObjectOutputStream objOutStream;

    //implement all the methods below
}

Создавайте экземпляр ObjectOutputStream только тогда, когда вы готовы это сделать. Остальные методы, которые вам необходимо реализовать в интерфейсах, могут просто вызывать те же методы в objOutStream

0
ответ дан 14 December 2019 в 19:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: