Вопрос

Despite there is lot of similar questions around this topic I cannot find any appropriate. This is about commonly used builder + entity approach such as Apache commons CLI OptionBuilder + Option and corresponding client code migration to Scala.

Illustration in code:

Java classes:

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);
    }

}

Normal Java code using this approach:

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

If this is 'fed' into scalac it complains about Builder not having hasF2 field. The point as from my investigation is Scala has no problem to locate Builder.hasF1 method as class level one but after this it needs to call static hasF2 for existing Java class istance and it has problems.

Any idea how this should be properly resolved?

UPDATE: Related question illustrating all mechanics: Scala error compiling OptionBuilder

Это было полезно?

Решение

You cannot do it. You cannot call static methods on instances in Scala. And, in fact, it is considered a bad practice in Java as well, but if that's the interface you have, there's really nothing you can do about it short of building a complete Scala wrapper.

Now, if that code is under your control, then all I can say is: don't do that. And, if you don't trust me, go see what Joshua Bloch has to say about it in Effective Java.

Другие советы

OK, in this case finally came to the following Scala solution:

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

Which clearly identifies original external library has bad design. My luck it is called at the start of application but I'm considering refactoring such cases in favor of direct Entity constructor calls because of potential side effects.

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

Does not return anything.

Because Builder.hasF1(5) returns nothing, obviously Scala can't find hasF2.

Modify hasF1:

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

And do the same for others.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top