Вы можете использовать Class или KClass для этого, но лучше использовать KClass для этого случая. В противном случае вам придется добавить .java
в класс, как упоминал Блю Джонс.
Я не уверен какое имя вы хотите. Помните, что может быть несколько классов JVM с одним и тем же именем. Closeable
для экземпляра может быть либо java.io.Closeable , либо пользовательской реализацией, если вы также используете библиотеку, которая использует ее по любой практической причине.
Учитывая это, существуют допустимые варианты использования, в которых вы хотите указать полное имя. Полное имя идентично «обычному» имени, за исключением того, что оно также включает пакет. Рассмотрим это для примера:
import java.io.Closeable;
fun main(ar: Array<String>){
val closeable = Closeable::class
println(closeable.simpleName)
println(closeable.qualifiedName)
}
Это напечатало бы:
Closeable
java.io.Closeable
Вам нужно будет выбрать тот, который вы хотите использовать, в зависимости от вашего использования. Если вы тоже хотите пакет, используйте qualifiedName
. В противном случае используйте simpleName
.
Вы, очевидно, не должны получать уроки, выполняя ClassName::class
. Вы также можете сделать то же самое на экземплярах, что означает, что вы можете сделать any::class
и использовать это, чтобы получить имя.
Итак, чтобы получить имя, используйте any::class.qualifiedName
. Если вы просто хотите, чтобы имя класса исключало пакет, используйте simpleName
.
Стоит отметить, что KClass является частью пакета отражения . Поэтому я предполагаю, что он использует отражение в нескольких или во всех вызовах.
Это означает, что вы можете получить SecurityException, если в разрешениях отказано. Я тестировал большую часть этого на try.kotlinlang.org , и я получил SecurityException с лямбда в основном методе при использовании KClass#qualifiedName
и KClass#simpleName
.
Использование ::class.java
исправило это. Так что, если вы испытываете исключения безопасности, используйте class.java
. Наименование практически идентично. simpleName
есть, но qualifiedName
просто name
. Какой из них вы выбираете, зависит от вас, но любой из них работает.
Итак, ваш код будет выглядеть так:
println(any::class.qualifiedName) // Alternatively with simpleName
println(any::class.java.name) // Alternatively with simpleName
И, наконец, я вижу, как вы назвали toString()
в одном из случаев. Это возвращает полное имя класса с хешем после него. Это тоже вариант, но если вам не нужен хеш, используйте Class или KClass.
Кроме того, я вижу, вы использовали MainActivity.log
в качестве своей функции. Я действительно не понимаю, почему. Если у вас есть функция ведения журнала, ограниченная одним классом, поместите ее в объект-компаньон. Объявление функций расширения внутри самого класса также бессмысленно, поскольку вызовы идентичны. Поскольку вы можете редактировать класс, а это единственный класс, о котором мы говорим, вы можете переместить его в объект-компаньон (опционально, сделать его закрытым).
И ваш код может выиграть от использования строковых шаблонов, которые я добавлю в последнем примере. Это должно гарантировать, что места заканчиваются правильно. С вашим текущим кодом нет места для добавления. Я также не могу найти Objects#getName()
, поэтому я предполагаю, что это еще одна попытка получить само имя. Однако: Класс Objects
при условии, что он java.util.Objects
не может быть инициализирован. Это служебный класс. Если вы имели в виду java.lang.Object
, используйте вместо него Any
. Any примерно такой же, как Object.
Что означает, что ваш класс может выглядеть так:
class MainActivity : Activity() {
...
companion object {
fun log(claz: Object, any: Any){
Log.d("Main", "${claz::class.java.name} ${any::class.qualifiedName}") // I'm mixing the calls here to show you that you can use either. You can of course pick which you use.
}
}
}