如何在kotlin中使用Android支持typedef注释?

cur*_*hov 33 android kotlin

我开发Android应用程序并经常使用注释作为编译时参数检查,主要是android的支持注释.

java代码中的示例:

public class Test
{
    @IntDef({Speed.SLOW,Speed.NORMAL,Speed.FAST})
    public @interface Speed
    {
         public static final int SLOW = 0;
         public static final int NORMAL = 1;
         public static final int FAST = 2;
    }

    @Speed
    private int speed;

    public void setSpeed(@Speed int speed)
    {
        this.speed = speed;
    }
}
Run Code Online (Sandbox Code Playgroud)

由于Android中的性能问题,我不想使用枚举.kotlin的自动转换器只生成无效代码.如何@IntDef在kotlin中使用注释?

Ron*_*tin 35

实际上,可以@IntDef通过将注释类之外的值定义为const vals 来使用支持注释.

使用你的例子:

import android.support.annotation.IntDef

public class Test {

    companion object {

         @IntDef(SLOW, NORMAL, FAST)
         @Retention(AnnotationRetention.SOURCE)
         annotation class Speed

         const val SLOW = 0L
         const val NORMAL = 1L
         const val FAST = 2L
    }

    @Speed
    private lateinit var speed: Long

    public fun setSpeed(@Speed speed: Long) {
        this.speed = speed
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,此时编译器似乎需要注释的Long类型@IntDef而不是实际的Ints.

  • 我已经这样做了,但Kotlin似乎根本没有强制执行这种约束.我可以提供任何需要`@ Speed`的int/long,而且它并不关心. (21认同)
  • 顺便说一句,它需要一个“ Long”,因为“ @IntDef”被定义为采用“ long”的数组-“ long [] value()default {};” (2认同)

Ale*_*lov 11

目前还没有办法在Kotlin中实现这一点,因为注释类不能有一个主体,因此你不能在其中声明一个将被处理的常量IntDef.我在跟踪器中创建了一个问题:https://youtrack.jetbrains.com/issue/KT-11392

但是对于你的问题,我建议你使用一个简单的枚举.


Oz *_*bat 5

只需将@IntDef类创建为java类并通过kotlin代码访问即可。

例:

1)创建您的类型类:

public class mType {
    @IntDef({typeImpl.type1, typeImpl.type2, typeImpl.type3})
    @Retention(RetentionPolicy.SOURCE)
    public @interface typeImpl {
        int type1 = 0;
        int type2 = 1;
        int type3 = 2;
    }
}
Run Code Online (Sandbox Code Playgroud)

2)将此函数放在任何Kotlin对象中:

object MyObject{
    fun accessType(@mType.typeImpl mType: Int) {
       ...
    }
}
Run Code Online (Sandbox Code Playgroud)

3)然后访问它:

fun somOtherFunc(){ 
        MyObject.accessType(type1)
 }
Run Code Online (Sandbox Code Playgroud)

**注意:您不必将访问方法放在对象内部。