【问题标题】:Extending 3rd party class as Hadoop Writable with proxy使用代理将 3rd 方类扩展为 Hadoop Writable
【发布时间】:2012-03-29 01:26:08
【问题描述】:

我有一个试图在 Hadoop 中使用的第三方类,因此需要让它实现 Writable。问题是Hadoop使用Writable的方式是先创建一个对象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() 构造函数,并且在检查DataInput 流之前我无法知道实际的size

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

谢谢!

【问题讨论】:

    标签: java serialization hadoop proxy-classes writable


    【解决方案1】:

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

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

    【讨论】:

    • 控制 Cube 是可能的,但这是不可取的,因为这意味着我必须维护上游更改。我认为胜利是值得的——有很多不受欢迎的属性(除了我提到的问题之外),这会导致大量不必要的复制和分配。我认为反射的想法是我最初的想法。我对细节一无所知,但这似乎很相关:docs.oracle.com/javase/1.3/docs/guide/reflection/proxy.html
    • 您只能使用带接口的代理,我仍然不确定这将如何解决您的final 问题
    猜你喜欢
    • 2015-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 2020-01-03
    • 2020-08-25
    • 2021-09-25
    相关资源
    最近更新 更多