android-Kotlin:从自身/内部引用匿名对象(通过此方法)
作者:互联网
TL; DR
这些对象:someClass {}匿名对象无法通过此对象访问自身(这将导致外部对象).我该如何访问?
更长的解释:
对于我的片段,我需要一个PreDrawListener.我在onCreateView中称呼它.执行时,我想随后删除监听器.因此,Java的操作方式将建议如下所示
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
val treeObserver = layout.viewTreeObserver
treeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
layout.viewTreeObserver.removeOnPreDrawListener(this)
...
}
}
问题是,当查看removeOnPreDrawListener(this)时,此对象不是侦听器,而是myFragment $onCreateView $1 @ f019bf0
另外,我可以访问this @ MyFragment,它直接返回对Fragment的引用.
尽管如此,这些选项似乎都不是我的PreDrawListener.如何从内部访问它(如果有的话)?
解决方法:
老实说,我看不到您的问题.
匿名内部的this表示类本身,但是它们从来没有名称.您不能使用名称创建匿名类.为了演示这一点,我编写了一些示例代码:
class TheClass{
fun run(){
val anon = object: Runnable {
override fun run() {}
}
println(anon::class.java.simpleName)
println(anon::class.java.name)
}
}
哪些打印:
run$anon$1
com.package.TheClass$run$anon$1
现在,一切都很好,但是看起来还是不像您的.但是您会看到它与包含的类,方法,变量以及最后一个表示它是匿名内部类的美元符号匹配.这适用于第二个,即完整的一个.第一个只是打印短名称,即方法,变量名,以及再次显示其匿名功能的美元符号.
如果您对为什么显示带有数字的美元符号感兴趣,请参见this.
让我们扩展它并抛弃变量.显然,这是可怕的代码(并且远非内存效率高,但这只是一个演示,因此没关系):
class TheClass {
fun run(){
println(object: Runnable {
override fun run() { }
})
}
}
打印,并匹配您的图案:
com.package.TheClass$run$anon$1
您已经看到了模式;现在您可以开始“解码”您得到的哈希:
myFragment // inside myFragment
$onCreateView // Inside a function
$1 // There is an anonymous class with a specific identifier
@f019bf0 // This is standard everywhere; just look up Object.toString()
我只是想证明的是:这确实是指您创建的匿名函数.匿名函数是匿名的.他们没有名字.他们使用$number作为标识符.因此,如果您有以下代码:
treeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
layout.viewTreeObserver.removeOnPreDrawListener(this)
...
}
}
这将引用侦听器,即使打印该类可能会打印出看起来令人困惑的内容.如果有什么问题,不是因为它没有指向侦听器(因为确实是这样)
另外,您的代码可以正常编译.那里也没有类型不匹配.如果它引用了另一个对象,则将其传递给需要OnPreDrawListener的方法将不起作用.
使用Java中的相同代码,您将获得不同的结果.这是因为Kotlin将匿名函数编译为Class $function $number,而Java将匿名函数编译为Class $number.如果在嵌套类中,它将在Kotlin中显示为Outer $Inner $function $number,在Java中显示为Outer $Inner $number.
编译器的不同导致名称不同. Java不包括该功能,而Kotlin则包括该功能.它位于.class文件名中,因此,如果您构建项目并在文件浏览器中查看具有任何操作系统的文件名(请不要在IntelliJ中查看.它将为您反编译文件.记住,您只是寻找名称,IntelliJ通过将.class文件合并为一个文件来匹配原始源,从而弄乱了名称)
就像最终的meta一样,我确实打印类而不是打印对象.接口没有重写的toString方法,这意味着它默认为Object上的方法,该方法返回getClass().getName()“ @” Integer.toHexString(hashCode());. (原始代码可以找到here). println(this)与println(this.toString())相同,后者在Object中调用toString方法,该方法将打印类名. println(this)与打印对象或打印类相同
标签:kotlin,this,anonymous-class,android 来源: https://codeday.me/bug/20191108/2008978.html