First, Answering the second question.
class Cls {
companion object {
val Obj = object {
val attr = 1
}
}
}
fun main() {
println(Cls.Obj.attr) // Error: "Unresolved reference: Obj"
println(Cls.Companion.Obj.attr) // Error: "Unresolved reference: Obj"
println(Cls.Obj) // ok
println(Cls.Companion.Obj) // ok
}
Here the object{} is called as anonymous object which is assigned to the variable as val object It does not have any references.

When you check here, Cls.Obj is of type Any.
So you cannot access like Any.attr because Any is root of all Kotlin class, it will only have default fucntions like hashcode(), equals()...
Since it is an anonymous object, you cannot do type cast.So no way to access attr directly.
To access attr , you can acheive with interface.
interface Foo{
fun attrs():Int
}
class Cls {
companion object {
val Obj = object : Foo{
var attr = 1
override fun attrs(): Int = attr
}
}
}
fun main() {
println(Cls.Obj.attrs()) // Print attr value 1
}
Here is the compiled code looks like of this.
public final class Cls public constructor() {
public companion object {
public final val Obj: kotlin.Any /* compiled code */
}
}
When you see here, Obj is a variable inside which is of type Any.
In Kotlin, you can access variables inside companion object in both ways with or without Companion. Both will work.
println(Cls.Obj) // ok
println(Cls.Companion.Obj) // ok
In java , we need to access like,
Cls.Companion.getObj().
In Kotlin ,Companion word can be ignored. So accessing variables in companion object is the better one without using companion,like below.
println(Cls.Obj) // ok
Coming to First Question
class Cls {
companion object {
object Obj {
val attr = 1
}
}
}
fun main() {
println(Cls.Obj.attr) // Error: "Unresolved reference: Obj"
println(Cls.Companion.Obj.attr) // ok
println(Cls.Obj) // Error: "Unresolved reference: Obj"
println(Cls.Companion.Obj) // ok
}
Here you use object inside companion object, which is a nested object. This is similar to Nested static class in java, but not the same.
public final class Cls public constructor() {
public companion object {
public object Obj {
public final val attr: kotlin.Int /* compiled code */
}
}
}
The above one is the compiled code of the first one. When you check here, you have object inside companion object. But in your second question, you have made that Obj as variable. So you can directly call that variable. But here since it is a nested object, you should use companion keyword to access Obj.
Cls.Companion.Obj is the valid one.
When you access Obj like this Cls.Obj, the compiler checks for variable named 'Obj' inside that companion object. But there is no such variable because its an nested object.
And to make it clear,here is another example.
class Cls {
companion object {
object Obj {
val attr = 1
}
object Obj1{
val attr = 2
}
}
}
Hope it helps you.