В Kotlin есть возможность написать имя класса вместо реализации интерфейса если интерфейс реализован companion object'ом этого класса:
interface Key
class Value {
companion object KeyImpl : Key {
...
}
}
// мы можем обратиться к реализации ключа по имени класса
val key1: Key = Value
// полная форма
val key2: Key = Value.KeyImpl
Если декомпилировать байт-код, сгенерированный для этого примера можно увидить что вместо имени класса подставляется companion оbject реализация:
public interface Key {}
public final class Value {
// companion object это статическое поле
// другими словами синглетон класса
public static final KeyImpl KeyImpl = new KeyImpl();
public static final class KeyImpl implements Key {}
}
// в обеих ситуациях используется полная форма
Key key1 = (Key) Value.KeyImpl;
Key key2 = (Key) Value.KeyImpl;Если честно я недавно узнал об этом когда в очередной раз залез в исходники корутин, если вы не знали в CoroutineContext'е используется аналогичный механизм для изящного извлечения элементов:
// вместо использования Job.Key используется имя класса
val job = coroutineContext[Job]
// аналогично с CoroutineDispatcher
val dispatcher = coroutineContext[CoroutineDispatcher]
Классы Job и CoroutineDispatcher содержат реализации ключей в своих companion object'ах, а CoroutineContext переопределяет оператор получения значения по ключу (квадратные скобки), поэтому такой код будет работать.
Пишите в комментах ваше мнение и всем хорошего кода!