Kotlin @JvmStatic和伴随对象中的意外覆盖

时间:2017-06-17 16:54:21

标签: swing kotlin

我正在研究Swing外观和感觉使用kotlin。为了创建UI,Swing需要一个带有以下签名的静态方法createUI

class ButtonUI: BasicButtonUI() {
    ...
    companion object {
        @JvmStatic fun createUI(p0: JComponent): ComponentUI {
           ...
        }
    }
}

然后通过Swing代码中的反射调用它:

m = uiClass.getMethod("createUI", new Class[]{JComponent.class});

不幸的是,由于以下原因,kotlin编译器无法编译上面的代码:

Error:(88, 9) Kotlin: Accidental override: The following declarations have the same JVM signature (createUI(Ljavax/swing/JComponent;)Ljavax/swing/plaf/ComponentUI;):
    fun createUI(c: JComponent): ComponentUI
    fun createUI(p0: JComponent!): ComponentUI!

这种情况有解决方法吗?

2 个答案:

答案 0 :(得分:3)

它是一个kotlin bug KT-12993。不幸的是,这个bug还没有修复。如果你想让kotlin实现你的ui逻辑,只需使用实现你的ButtonUI或在和kotlin之间切换来解决问题。例如,您应该在和kotlin之间定义 peer

java代码如下:

public class ButtonUI extends BasicButtonUI {
    private ButtonUIPeer peer;

    public ButtonUI(ButtonUIPeer peer) {
        this.peer = peer;
    }

    @Override
    public void installUI(JComponent c) {
        peer.installUI(c, () -> super.installUI(c));
    }

    // override other methods ...


    public static ComponentUI createUI(JComponent c) {
        // create the peer which write by kotlin 
        //                        |
        return new ButtonUI(new YourButtonUIPeer());
    }
}


interface ButtonUIPeer {
    void installUI(Component c, Runnable parentCall);
    //adding other methods for the ButtonUI
}

kotlin代码如下:

class YourButtonUIPeer : ButtonUIPeer {
    override fun installUI(c: Component, parentCall: Runnable) {
      // todo: implements your own ui logic
    }
}

IF 您有超过六种方法可以实现,您可以使用Proxy Design Pattern委托给kotlin中实现的目标ButtonUI的请求(许多IDE支持生成委托一个领域的方法)。例如:

public class ButtonUIProxy extends BasicButtonUI {
    private final BasicButtonUI target;
    //1. move the cursor to here ---^
    //2. press `ALT+INSERT`
    //3. choose `Delegate Methods` 
    //4. select all public methods and then click `OK`

    public ButtonUIProxy(BasicButtonUI target) {
        this.target = target;
    }

    public static ComponentUI createUI(JComponent c){
        // class created by kotlin     ---v
        return new ButtonUIProxy(new ButtonUI());
    }
}

答案 1 :(得分:0)

在最新版本的Kotlin 1.3.70中,可以使用@Suppress("ACCIDENTAL_OVERRIDE")来抑制该错误。我不确定从哪个版本开始。