我有一个第三方类,我试图在 Hadoop 中使用它,因此需要让它实现Writable
。问题是Hadoop使用Writable
的方式是创建一个对象o = SomeObject()
,然后调用o.readFields(in)
来反序列化,在我的情况下我无法创建空对象:
public abstract class Cube {
protected final int size;
protected Cube(int size) { this.size = size; }
}
注意大小
是最终
。
public class RealCube {
public Cube(int size) { super(size); }
}
这里RealCube
只有一个 super 构造函数可以调用,并且该构造函数在抽象父类(super class)中设置final
变量。
public class RealCubeWritable implements Writable {
public void readFields(DataInput in) {
/* yikes! need to set the size */
}
}
当我们开始尝试实现 RealCubeWritable
时,我无法拥有 RealCubeWritable()
构造函数,并且我无法知道实际的大小
直到检查 DataInput
流。
因此,在 Hadoop 中执行此操作的唯一方法似乎是使用包装器。我想知道是否有一种方法可以使用包装器,但 RealCubeWritable
仍然表现得像 RealCube
?我研究过使用动态代理类,但我不确定这是否有效(或如何实际执行)。
谢谢!
最佳答案
如果您确实无法控制 Cube 对象,那么我不确定您是否有很多(令人愉快的)选项:
- 我不确定我是否理解包装器或代理对象的含义 - 无论哪种方式,最终都是最终的,因此您需要创建不带最终标志的类的副本
- 您也许可以使用令人讨厌的反射黑客来取消大小字段的最终确定,然后也通过反射设置字段值,但是如果 Cube 从大小中初始化其他变量,则可能会导致一些未定义的行为构造函数
- 您可以编写自己的 Serialization类,它允许您为每个对象创建一个新的 RealCube 实例(不是最有效的,但它会起作用)(而不是利用传统的 hadoop 对象重用)
size
的域相对较小吗? (即它只能是有限的值集/范围)。如果是这样,您可以为每个有效的大小值创建一个 RealCube 实例,然后再次使用自定义序列化实现,根据从输入流读取的大小选择正确的 Cube 实例
关于java - 使用代理将第 3 方类扩展为 Hadoop Writable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9917974/