Kotlin Annotation IntDef

时间:2016-06-15 10:52:32

标签: annotations kotlin

我有这个代码示例:

class MeasureTextView: TextView {
    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)

    companion object{
        val UNIT_NONE = -1
        val UNIT_KG = 1
        val UNIT_LB = 0            
    }

    fun setMeasureText(number: Float, unitType: Int){

        val suffix = when(unitType){
            UNIT_NONE -> {
                EMPTY_STRING
            }
            UNIT_KG -> {
                KG_SUFIX
            }
            UNIT_LB -> {
                LB_SUFIX
            }
            else -> throw IllegalArgumentException("Wrong unitType passed to formatter: MeasureTextView.setMeasureText")
        }

        // set the final text
        text = "$number $suffix"
    }
}

我希望能够在编译时使用自动完成功能和IntDef注释,所以当我调用setMeasureText(...)时, 静态变量显示为此方法的参数的选项。

我已经搜索了这个,我无法找到Kotlin是否支持这种java风格的注释(例如intdef)。所以我已经尝试了,并为此做了一个注释,但它不会在自动完成中显示。

我的问题: - Kotlin(最新版本)支持Java注释IntDef

  • 如果是,我如何在Android Studio IDE中打开(如果有效,我无法让编译器建议)。

  • 如果不是,是否有任何Kotlin方式进行此编译时检查

7 个答案:

答案 0 :(得分:33)

奇怪的是,这个问题在right answer

之前的搜索中出现

在此处复制:

import android.support.annotation.IntDef
public class Test {

    companion object {

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

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

    @Speed
    private var speed: Int=SLOW

    public fun setSpeed(@Speed speed: Int) {
        this.speed = speed
    }
}

答案 1 :(得分:19)

从Kotlin 1.0.3开始,不支持@IntDef注释,但计划为更高版本提供支持。

进行这些编译时间检查的Kotlin方法是使用enum class而不是一系列Int常量。

答案 2 :(得分:2)

如果您从Java调用setMeasureText,您也可以通过在Java中创建IntDef来使其工作

// UnitType.java
@Retention(RetentionPolicy.SOURCE)
@IntDef({MeasureText.UNIT_KG, MeasureText.UNIT_LB, MeasureText.UNIT_NONE})
public @interface UnitType {}

h / t Tonic Artos

您还需要更新您的随播广告对象,以使您的值更长且可公开访问

companion object{
    const val UNIT_NONE = -1L
    const val UNIT_KG = 1L
    const val UNIT_LB = 0L
}

答案 3 :(得分:1)

尝试一下:

companion object {
    const val VALUE_1: Int = 1
    const val VALUE_2: Int = 2
    const val VALUE_3: Int = 3
}

@IntDef(value = [VALUE_1, VALUE_2, VALUE_3])
@Retention(AnnotationRetention.SOURCE)
annotation class TestClassName

答案 4 :(得分:1)

关于讨论 koltin 枚举或 java 注释,我在 android 中做了一个简单的测试,创建一个库项目并反编译它以查看文件大小。

Kotlin 枚举类 TestEnum

enum class TestEnum {
     ENUM1,
     ENUM2,
     ENUM3,
     ENUM4,
     ENUM5,
     ENUM6,
     ENUM7,
     ENUM8,
     ENUM9,
     ENUM11,
     ENUM12,
     ENUM13,
     ENUM14,
     ENUM15,
     ENUM16,
     ENUM17,
     ENUM18,
}

Java 接口 TestInterface

@Retention(RetentionPolicy.SOURCE)
@StringDef(
        {
                ENUM1,
                ENUM2,
                ENUM3,
                ENUM4,
                ENUM5,
                ENUM6,
                ENUM7,
                ENUM8,
                ENUM9,
                ENUM11,
                ENUM12,
                ENUM13,
                ENUM14,
                ENUM15,
                ENUM16,
                ENUM17,
                ENUM18,
        }
)
public @interface TestInterface {
    public static final String ENUM1 = "ENUM1";
    public static final String ENUM2 = "ENUM2";
    public static final String ENUM3 = "ENUM3";
    public static final String ENUM4 = "ENUM4";
    public static final String ENUM5 = "ENUM5";
    public static final String ENUM6 = "ENUM6";
    public static final String ENUM7 = "ENUM7";
    public static final String ENUM8 = "ENUM8";
    public static final String ENUM9 = "ENUM9";
    public static final String ENUM11 = "ENUM11";
    public static final String ENUM12 = "ENUM12";
    public static final String ENUM13 = "ENUM13";
    public static final String ENUM14 = "ENUM14";
    public static final String ENUM15 = "ENUM15";
    public static final String ENUM16 = "ENUM16";
    public static final String ENUM17 = "ENUM17";
    public static final String ENUM18 = "ENUM18";
}

如果你构建发布(我使用默认的新 android 项目 gradle 构建)这是文件大小的结果:

enter image description here

你自己决定你喜欢使用哪个

如果你的所有项目都在 Kotlin 中,你就别无选择,甚至像 @ColorRes 这样的资源注释也不起作用。示例:创建一个数据类,注释一个属性,尝试给一个错误的值,lint 不会显示错误

答案 5 :(得分:0)

将IntDef与Kotlin结合使用的首选方法是使用顶层声明:

package com.example.tips


const val TIP_A = 1
const val TIP_B = 2
const val TIP_C = 3

@IntDef(TIP_A, TIP_B, TIP_C)
@Retention(AnnotationRetention.SOURCE)
annotation class TipId


class TipsDataProvider {

    fun markTip(@TipId tipId: Int) {
    ...
    }
}

不需要额外的类或对象! 有关顶级声明here的更多信息。

答案 6 :(得分:0)

如已接受的回答所述,在Kotlin中使用enum class

我写了所问问题的具体代码,它可能对科特林的新人有帮助:

class MeasureTextView: TextView {
   enum class UnitType(val value : Int){
       UNIT_NONE(-1),
       UNIT_KG(0),
       UNIT_LB(1)
   }

   fun setMeasureText(number: Float, unitType: UnitType){
       val suffix = unitType.value
   }
}