I honestly don't see your problem.
this
inside an anonymous refers to the class itself, but they never have names. You can't create an anonymous class with a name. To demo this, I wrote some sample code:
class TheClass{
fun run(){
val anon = object: Runnable {
override fun run() {}
}
println(anon::class.java.simpleName)
println(anon::class.java.name)
}
}
Which prints:
run$anon$1
com.package.TheClass$run$anon$1
Now, this is nice and all, but it still doesn't look like yours. But you see it matches the containing class, method, variable, and finally the dollar sign denoting that it's an anonymous inner class. That applies to the second, which is the full one. The first just prints the short name, which is the method, var name, and again the dollar sign that shows it's anonymous function.
If you're interested in why the dollar sign with a number appears, see this. T
Let's expand that and ditch the variable. Obviously, this is horrible code (and far from memory-efficient, but it's a demo so it doesn't matter):
class TheClass {
fun run(){
println(object: Runnable {
override fun run() { }
})
}
}
This prints, and matching your pattern:
com.package.TheClass$run$anon$1
You've seen the pattern; now you can start "decoding" the hash you got:
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()
What I just tried to prove is: this
does refer to the anonymous function you create. Anonymous functions are, well, anonymous. They don't have names. They use $number
as identifiers. So if you have this code:
treeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
layout.viewTreeObserver.removeOnPreDrawListener(this)
...
}
}
this
will refer to the listener, even though printing the class may print stuff that looks confusing. If there's something that's broken, it's not because of this
not referring to the listener (because it does)
Also, your code compiles fine. There's no type mismatch in there either. If it referred to a different object, it wouldn't work if you passed this
to a method that requires a OnPreDrawListener
.
You would get a different result with the same code in Java. This is because Kotlin compiles anonymous functions as Class$function$number
, where as Java compiles it to Class$number
. If it's in a nested class, it will appear as Outer$Inner$function$number
in Kotlin, and Outer$Inner$number
in Java.
It's a difference in the compiler that results in different names; Java excludes the function, where as Kotlin includes it. It's in the .class
filename, so if you build your project and look at the file names in a file explorer for whatever OS you have (Do not look in IntelliJ. It will decompile the files for you. And remember, you're just looking for the name, which IntelliJ messes up by merging the .class files into a single one to match the original source)
Just as final meta, I do print the class instead of printing the object. Interfaces do not have an overridden toString method, which means it defaults to the one on Object, which returns getClass().getName() + "@" + Integer.toHexString(hashCode());
(original code can be found here). println(this)
is the same as println(this.toString())
, which calls the toString method in Object, which prints the class name. println(this)
is the same as printing the object or printing the class