如何从Scala调用现有Java类实例的公共静态方法?

时间:2014-05-01 17:06:53

标签: java scala oop static

尽管围绕这个主题有很多类似的问题,我找不到任何合适的问题。这是关于常用的构建器+实体方法,例如Apache commons CLI OptionBuilder + Option以及相应的客户端代码迁移到Scala。

代码中的插图:

Java类:

public class Entity {

    private int f1;
    private int f2;

    public Entity(int f1, int f2) {
        this.f1 = f1;
        this.f2 = f2;
    }
}

public class Builder {

    private static int f1 = 0;
    private static int f2 = 0;

    private static Builder instance = new Builder();

    static Builder hasF1(int f1) {
        Builder.f1 = f1;
        return Builder.instance;
    }

    static Builder hasF2(int f2) {
        Builder.f2 = f2;
        return Builder.instance;
    }

    static Entity create() {
        return new Entity(Builder.f1, Builder.f2);
    }

}

使用此方法的普通Java代码:

Entity entity = Builder.hasF1(5).hasF2(10).create();

如果这是“喂养”#39;进入scalac抱怨Builder没有hasF2字段。从我的调查来看,Scala将Builder.hasF1方法定位为class level one没有问题,但在此之后,它需要为现有的Java类istance调用静态hasF2,并且它有问题。

知道如何正确解决这个问题吗?

更新: 说明所有机制的相关问题:Scala error compiling OptionBuilder

3 个答案:

答案 0 :(得分:8)

你不能这样做。您不能在Scala中的实例上调用静态方法。事实上,它在Java中也被认为是一种不好的做法,但如果这就是你所拥有的界面,那么除了构建一个完整的Scala包装器之外,你真的无能为力。

现在,如果该代码位于您的控件下,那么我只能说:不要那样做。而且,如果你不相信我,请看看Joshua Bloch在Effective Java中对此有何看法。

答案 1 :(得分:1)

好的,在这种情况下,最终得到了以下Scala解决方案:

Builder.hasF1(5)
Builder.hasF2(10)
Entity entiry = Builder.create()

其中明确标识原始外部库的设计不好。我很幸运,它在应用程序启动时被调用,但我考虑重构这些情况,支持直接Entity构造函数调用,因为它可能会产生副作用。

答案 2 :(得分:0)

static Builder hasF1(int f1) {
    Builder.f1 = f1;
}

不返回任何内容。

由于Builder.hasF1(5)没有返回任何内容,显然Scala无法找到hasF2

修改hasF1:

static Builder hasF1(int f1) {
    Builder.f1 = f1;
    return Builder;
}

为其他人做同样的事。