Kotlin @JvmStatic和意外覆盖伴侣对象

我正在使用kotlin处理Swing的外观和感觉。 为了创建一个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! 

有这种情况下的解决方法吗?

这是一个kotlin 错误KT-12993 。 不幸的是,这个bug还没有被修正。 只是使用java实现你的ButtonUI或者在java和kotlin之间切换来解决问题,如果你想让kotlin实现你的UI逻辑。 例如,你应该在java和kotlin之间定义一个对等体。

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

如果你有超过六十种实现方法,你可以使用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()); } } 
Interesting Posts