我正在尝试为日志记录创建扩展功能。我想发送Any
作为参数并获取其名称。但是找不到如何获取Any
类的名称。有什么想法吗?
fun MainActivity.log(claz: Objects,any: Any){
Log.d("Main", claz.name + any.toString())
}
答案 0 :(得分:2)
使用yourClassInstance::class.simpleName
:
fun MainActivity.log(claz: Objects, any: Any){
Log.d("Main", "${claz::class.simpleName} ${any::class.simpleName}")
}
答案 1 :(得分:1)
O(n^3.log(n))
答案 2 :(得分:1)
您可以为此使用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是a part of the reflection package。因此,我认为它在一些或所有调用中都使用了反射。
这意味着如果权限被拒绝,则可以获取SecurityException。我在try.kotlinlang.org上测试了其中的大部分内容,并且在使用KClass#qualifiedName
和KClass#simpleName
时,main方法中的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
。任何都与对象大致相同。
这意味着您的班级可能看起来像这样:
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.
}
}
}
答案 3 :(得分: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
}
}