Котлин Аннотация IntDef

У меня есть этот пример кода:

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). Итак, я попробовал это и сделал для этого аннотацию, но в автозаполнении она не будет отображаться.

Мой вопрос: - Поддерживается ли аннотация Java IntDef в Kotlin (последняя версия)

  • Если это так, как я могу включить ON в Android Studio IDE (если он работает, я не могу заставить компилятор предложить это).

  • Если это не так, существует ли какой-либо Kotlin-способ проверки времени компиляции?

7 ответов

Решение

Начиная с Kotlin 1.0.3, @IntDef аннотация не поддерживается, но поддержка планируется для более поздних версий.

Kotlin способ сделать эти проверки времени компиляции заключается в использовании enum class вместо серии Int константы.

Странная вещь, но этот вопрос приходит в поиск раньше того же с правильным ответом

Копирую это здесь:

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

Мой предпочтительный способ использовать 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) {
    ...
    }
}

Никаких дополнительных классов или объектов не требуется! Подробнее о объявлениях верхнего уровня здесь.

Если вы звоните setMeasureText из Java вы можете заставить его работать, создав свой IntDef в Java тоже

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

х / т Тоник Артос

Вам также нужно будет обновить объект-компаньон, чтобы сделать ваши значения длинными и общедоступными.

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

Попытайся:

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 KlssName {

}

Что касается обсуждения koltin enum или java-аннотации, я провел простой тест в android, создав проект библиотеки и декомпилировав его, чтобы увидеть размеры файлов.

Kotlin enum класс 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";
}

И если вы создаете выпуск (я использую новую сборку Gradle проекта Android по умолчанию), это результат размера файла:

Вы сами решаете, какой из них вам больше нравится

Как сказано в принятом ответе, используйте enum class в котлине.

Я написал конкретный код заданного вопроса, он может помочь некоторым новичкам в kotlin:

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
   }
}
Другие вопросы по тегам