简体   繁体   English

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

[英]How to invoke public static method for existing Java class instance from Scala?

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. 这是关于常用的构建器+实体方法,例如Apache commons CLI OptionBuilder + Option以及将相应的客户端代码迁移到Scala。

Illustration in code: 代码示例:

Java classes: 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);
    }

}

Normal Java code using this approach: 使用这种方法的普通Java代码:

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

If this is 'fed' into scalac it complains about Builder not having hasF2 field. 如果将它“喂”到了scalac它会抱怨Builder没有hasF2字段。 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. 从我的调查来看,Scala可以毫无问题地将Builder.hasF1方法定位为class level one但是在此之后,它需要为现有的Java类距离调用static hasF2,这是有问题的。

Any idea how this should be properly resolved? 任何想法应该如何正确解决?

UPDATE: Related question illustrating all mechanics: Scala error compiling OptionBuilder 更新:说明所有机制的相关问题: Scala错误编译OptionBuilder

You cannot do it. 你做不到。 You cannot call static methods on instances in Scala. 您不能在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. 而且,实际上,这在Java中也被认为是不好的做法,但是,如果这是您所拥有的接口,那么除了构建完整的Scala包装器之外,您实际上无能为力。

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. 而且,如果您不信任我,请去看看Joshua Bloch在Effective Java中对此有何评论。

OK, in this case finally came to the following Scala solution: 好的,在这种情况下,终于来到了以下Scala解决方案:

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. 幸运的是,它在应用程序开始时就被调用了,但是由于潜在的副作用,我正在考虑将这种情况重构为直接的Entity构造函数调用。

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

Does not return anything. 不返回任何东西。

Because Builder.hasF1(5) returns nothing, obviously Scala can't find hasF2 . 因为Builder.hasF1(5)返回任何内容,所以显然Scala找不到hasF2

Modify hasF1: 修改hasF1:

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

And do the same for others. 并为他人做同样的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM