Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 如何获取任何类的名称?_Kotlin - Fatal编程技术网

Kotlin 如何获取任何类的名称?

Kotlin 如何获取任何类的名称?,kotlin,Kotlin,我正在尝试为日志制作一个扩展函数。我想将Any作为参数发送并获取其名称。但是找不到如何获取任何类的名称。你知道吗 fun MainActivity.log(claz: Objects,any: Any){ Log.d("Main", claz.name + any.toString()) } 使用yourClassInstance::class.simpleName: fun MainActivity.log(claz: Objects, any: Any){ Log.

我正在尝试为日志制作一个扩展函数。我想将
Any
作为参数发送并获取其名称。但是找不到如何获取
任何
类的名称。你知道吗

fun MainActivity.log(claz: Objects,any: Any){
    Log.d("Main", claz.name +  any.toString())
}

使用
yourClassInstance::class.simpleName

fun MainActivity.log(claz: Objects, any: Any){
    Log.d("Main", "${claz::class.simpleName} ${any::class.simpleName}")
}

您可以使用类或KClass来实现这一点,但在这种情况下使用KClass是最好的。否则,正如Blue Jones所提到的,您必须向类中添加
.java

我不知道你要哪个名字。请记住,可以有多个同名的JVM类。实例的
Closeable
既可以是一个实例,也可以是一个自定义实现,如果您还使用一个库,该库出于任何实际原因使用它

考虑到这一点,有一些有效的用例需要限定名称。限定名称与“常规”名称相同,只是它还包括包。考虑这个例子:

import java.io.Closeable;

fun main(ar: Array<String>){
    val closeable = Closeable::class
    println(closeable.simpleName)
    println(closeable.qualifiedName)
}
你必须选择你想要使用的,这取决于你的使用。如果您也需要该软件包,请使用
qualifiedName
。否则使用
simpleName

显然,您不必通过执行
ClassName::class
来获取类。您也可以在实例上执行相同的操作,这意味着您可以执行
any::class
,并使用它来获取名称

因此,为了获得名称,请使用
any::class.qualifiedName
。如果只需要不包含包的类名,请使用
simpleName

值得注意的是,KClass是。因此,我假设它在少数或所有调用中使用反射

这意味着,如果权限被拒绝,您可以获得SecurityException。我在上测试了大部分内容,在使用
KClass#qualifiedName
KClass#simpleName
时,我在主方法中使用lambda得到了一个SecurityException

使用
::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
作为函数。我真的不明白为什么。如果您有一个仅限于单个类的日志函数,请将其放在伴生对象中。在类本身内部声明扩展函数也是毫无意义的,因为调用是相同的。由于您可以编辑该类,并且它是我们正在讨论的单个类,因此您可以将其移动到伴随对象(可选地,将其设置为私有)

您的代码可以从使用字符串模板中获益,我将在最后一个示例中添加这些模板。这是为了确保空间最终正确。使用当前代码,不会添加任何空间。我也找不到
对象#getName()
,因此我认为这是获取名称本身的另一次尝试但是:对象类,假设它是
java.util.Objects
无法初始化。这是一个实用类。如果您的意思是
java.lang.Object
,请改用
Any
。任何对象都与对象大致相同

这意味着你的班级可能是这样的:

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

我需要类似的东西来将原始json响应映射为对象,并设法使其工作如下

val depositResponse = convertResponseToObject(response , DepositResponse ::class.java.name) as DepositResponse
val withdrawResponse = convertResponseToObject(response , WithdrawResponse ::class.java.name) as WithdrawResponse
fun convertResponseToObject(response: String?, type: String ): Any{
    try {
        when (type) {
            DepositResponse ::class.java.name -> 
                 return ObjectMapper().readValue(response, DepositResponse ::class.java)
            WithdrawResponse ::class.java.name -> 
                 return ObjectMapper().readValue(response, WithdrawResponse ::class.java)
            else -> throw Exception("Error Mapping the json response")
        }
    }catch(e:Exception){
        throw e
    }
}

请注意,使用::class将导致实例化实际的类。在某些情况下,这可能会产生不好的副作用。@AndroidDev如果在构造函数中有副作用,则需要担心更大的问题,然后才能得到它的名称。@AndroidDev它不会实例化实际的类。检查hashCode,它始终保持不变。您必须调用()或TYPE::class.java.newInstance()来实例化新实例。
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.
        }
    }
}
val depositResponse = convertResponseToObject(response , DepositResponse ::class.java.name) as DepositResponse
val withdrawResponse = convertResponseToObject(response , WithdrawResponse ::class.java.name) as WithdrawResponse
fun convertResponseToObject(response: String?, type: String ): Any{
    try {
        when (type) {
            DepositResponse ::class.java.name -> 
                 return ObjectMapper().readValue(response, DepositResponse ::class.java)
            WithdrawResponse ::class.java.name -> 
                 return ObjectMapper().readValue(response, WithdrawResponse ::class.java)
            else -> throw Exception("Error Mapping the json response")
        }
    }catch(e:Exception){
        throw e
    }
}