gpt4 book ai didi

android - Kotlin:从自身/内部引用匿名对象(通过 this)

转载 作者:太空宇宙 更新时间:2023-11-03 13:40:54 29 4
gpt4 key购买 nike

长话短说这些 object : someClass{ } 匿名对象无法通过 this 访问自身(这导致了外部对象)。 我如何访问它?

更长的解释:

对于我的 Fragment,我需要一个 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) 时,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

现在,一切都很好,但它看起来仍然不像你的。但是你看到它匹配包含的类、方法、变量,最后是美元符号,表示它是一个匿名内部类。这适用于第二个,也就是完整的那个。第一个只打印短名称,即方法、var 名称和显示它是匿名函数的美元符号。

如果您对为什么出现带有数字的美元符号感兴趣,请参阅 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()

我刚才试图证明的是:this 确实引用了您创建的匿名函数。匿名函数是匿名的。他们没有名字。他们使用 $number 作为标识符。所以如果你有这段代码:

treeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
layout.viewTreeObserver.removeOnPreDrawListener(this)
...
}
}

this 将引用监听器,即使打印该类可能会打印出看起来令人困惑的内容。如果有什么东西坏了,那不是因为 this 没有引用监听器(因为它确实引用了)

此外,您的代码编译正常。那里也没有类型不匹配。如果它引用不同的对象,如果您将 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 文件合并为一个文件以匹配原始来源而弄乱了这个名称)


就像最终的元数据一样,我打印类而不是打印对象。接口(interface)没有重写的 toString 方法,这意味着它默认为 Object 上的方法,返回 getClass().getName() + "@"+ Integer.toHexString(hashCode()); (可以找到原始代码 here )。 println(this)println(this.toString())一样,都是调用Object中的toString方法,打印类名。 println(this) 与打印对象或打印类相同

关于android - Kotlin:从自身/内部引用匿名对象(通过 this),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52225779/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com