如何获取任何班级的名称?

问题描述 投票:0回答:5

我正在尝试制作一个用于日志记录的扩展功能。我想将

Any
作为参数发送并获取其名称。但找不到如何获取
Any
类的名称。有什么想法吗?

fun MainActivity.log(claz: Objects,any: Any){
    Log.d("Main", claz.name +  any.toString())
}
kotlin class
5个回答
6
投票
val c = String::class
println(c.simpleName)

$ String

4
投票

使用

yourClassInstance::class.simpleName

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

2
投票

您可以使用 Class 或 KClass,但在这种情况下使用 KClass 是最好的。否则,您必须将

.java
添加到类中,正如 Blue Jones 提到的那样。

我不确定您想要哪个名字。请记住,可以有多个同名的 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 上测试了大部分内容,当使用

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

您的代码可以受益于使用字符串模板,我将在最后一个示例中添加该模板。这是为了确保空格最终正确。使用您当前的代码,没有添加空间。我也找不到

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

1
投票

我需要类似的东西来将原始 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
    }
}

0
投票
println(any::class.simpleName)
println(any::class.qualifiedName)
println(any::class.name)

println(any::class.javaObjectType.name)
println(any::class.javaObjectType.canonicalName)
println(any::class.javaObjectType.simpleName)
println(any::class.javaObjectType.typeName)

println(any.javaClass.simpleName)
println(any.javaClass.canonicalName)
println(any.javaClass.typeName)
println(any.javaClass.name)

println(any::class.java.simpleName)
println(any::class.java.typeName)
println(any::class.java.name)
println(any::class.java.canonicalName)
© www.soinside.com 2019 - 2024. All rights reserved.