0

我有一个我想在 Hadoop 中使用的第三方类,因此需要让它实现Writable。问题是 Hadoop 使用的方式Writable是创建一个 object o = SomeObject(),然后调用o.readFields(in)反序列化,在我的情况下我无法创建空对象:

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

注意sizefinal

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()我无法知道实际情况。sizeDataInput

因此,在 Hadoop 中执行此操作的唯一方法似乎是使用包装器。我想知道是否有一种方法可以使用包装器,但RealCubeWritable仍然表现得像RealCube?我已经研究过使用动态代理类,但我不确定这是否可行(或如何实际执行)。

谢谢!

4

1 回答 1

1

如果您真的无法控制 Cube 对象,那么我不确定您是否有很多(令人愉快的)选项:

  • 我不确定我理解你所说的包装器或代理对象是什么意思 - 无论哪种方式 final 都是 final 所以你需要创建一个没有 final 标志的类的副本
  • 您可能可以使用令人讨厌的反射黑客来允许您取消最终大小字段,然后也通过反射设置字段值,但是如果 Cube 在构造函数中从大小初始化其他变量,这可能会导致一些未定义的行为
  • 您可以编写自己的序列化类,这将允许您为每个对象创建一个新的 RealCube 实例(不是最有效的,但它会工作)(而不是利用传统的 hadoop 对象重用)
  • 是不是域size比较小?(即它只能是一组有限的值/范围)。如果是这样,您可以为每个有效的大小值创建一个 RealCube 实例,然后再次使用自定义序列化实现,根据从输入流中读取的大小选择正确的 Cube 实例
于 2012-03-29T01:57:35.410 回答