Расширение стороннего класса как Hadoop, доступного для записи с прокси - PullRequest
0 голосов
/ 29 марта 2012

У меня есть сторонний класс, который я пытаюсь использовать в Hadoop, и поэтому мне нужно, чтобы он реализовал Writable. Проблема в том, что Hadoop использует Writable для создания объекта o = SomeObject(), затем вызывает o.readFields(in) для десериализации, и в моей ситуации я не могу создать пустой объект:

public abstract class Cube {
    protected final int size;
    protected Cube(int size) { this.size = size; }
}

Примечание size - final.

public class RealCube {
    public Cube(int size) { super(size); }
}

Здесь RealCube имеет только один супер-конструктор для вызова, и этот конструктор устанавливает переменную final в абстрактном суперклассе.

public class RealCubeWritable implements Writable {
    public void readFields(DataInput in) {
        /* yikes! need to set the size */
    }
}

Когда мы приступаем к реализации RealCubeWritable, у меня не может быть конструктора RealCubeWritable(), и я не могу знать фактический size, пока не будет проверен поток DataInput.

Так что, похоже, единственный способ сделать это в Hadoop - это использовать обертку. Что мне интересно, если есть способ использовать обертку, но RealCubeWritable по-прежнему ведет себя как RealCube? Я изучал использование классов динамического прокси, но я не уверен, сработает ли это (или как на самом деле это сделать).

Спасибо!

1 Ответ

1 голос
/ 29 марта 2012

Если вы действительно не можете контролировать объект Cube, тогда я не уверен, что у вас есть много (приятных) вариантов:

  • Я не уверен, что понимаю, что вы подразумеваете под оберткой илипрокси-объект - в любом случае final является окончательным, поэтому вам нужно будет создать копию класса без окончательных флагов
  • Возможно, вы сможете использовать мерзкий взлом отражения, чтобы позволить вам завершить поле размера, а затем задайте значение поля также с помощью отражения, но это может вызвать некоторое неопределенное поведение, если Cube инициализирует другие переменные из размера в конструкторе
  • . Вы можете написать свой собственный класс Serialization , который будетпозволяют вам создать новый экземпляр RealCube (не самый эффективный, но он будет работать) для каждого объекта (вместо использования традиционного повторного использования объекта hadoop)
  • Является ли домен size относительно маленьким?(т.е. это может быть только ограниченный набор / диапазон значений).Если это так, вы можете создать экземпляр RealCube для каждого действительного значения размера и снова, используя пользовательскую реализацию сериализации, выбрать правильный экземпляр Cube на основе размера, считанного из входного потока
...