How does `kotlin.Any` differ from `java.lang.Object`? What happens to the extra `Object` methods when running on the JVM?
answer
- Same runtime class, slimmer API
- Any = equals/hashCode/toString only
- wait/notify/getClass hidden
- Use ::class, .javaClass, synchronized{}
- Multiplatform reason for the trim
basics
~10 sAny is Kotlin's root and only promises equals, hashCode, toString. Object has extra methods like wait, notify, getClass. On the JVM Any maps to Object, so those extras still exist but Kotlin hides them.
solid answer
~40 s`kotlin.Any` is the declared root of the Kotlin type hierarchy and exposes only `equals`, `hashCode`, `toString`. `java.lang.Object` additionally has `getClass`, `wait`/`wait(long)`, `notify`/`notifyAll`, `finalize`, and `clone`. On the JVM, `Any` is **mapped** to `Object` at the bytecode level (they are the same runtime class), but the Kotlin compiler intentionally does **not** surface the threading/reflection extras on the `Any` API. To call them you go through other channels: `obj::class` or `obj.javaClass` for the class, and `(lock as Object).wait()`/`notify()` — though idiomatic Kotlin uses `synchronized`, `java.util.concurrent` locks, or coroutines instead. Kotlin also has no synchronized methods or `volatile` keyword; you use `@Synchronized`, `synchronized(lock){}`, and `@Volatile`. This slimmer surface keeps the type system multiplatform-friendly.
code
kotlin · 6 linesval o = Any()
println(o.toString()) // Any -> Object.toString()
val c = o.javaClass // reach Object.getClass()
synchronized(o) { // idiomatic, not o.wait()
// critical section
}go deeper
Knows Any has only three methods and Object has more.
Explains the JVM mapping (Any == Object at runtime) and which extras are hidden.
Justifies the trim (multiplatform + better idioms) and shows the replacement APIs (::class, synchronized, @Volatile).
Reasons about common-stdlib design across JVM/JS/Native and the cost/benefit of exposing platform-specific members on a universal root.
## Same runtime class, different declared API On the JVM, **`kotlin.Any` is compiled to `java.lang.Object`** — they are the *same* class at runtime. The difference is what the Kotlin compiler lets you *see* and *call* through the `Any` static type. `Any` declares only: - `open operator fun equals(other: Any?): Boolean` - `open fun hashCode(): Int` - `open fun toString(): String` `java.lang.Object` additionally has `getClass()`, `wait()`/`wait(long)`/`wait(long, int)`, `notify()`, `notifyAll()`, `finalize()`, and `clone()`. Kotlin deliberately **omits** these from the `Any` surface. ## Why omit them? - **Multiplatform.** `Any` must exist on JS and Native too, where `wait`/`notify`/`getClass` make no sense. - **Better idioms exist.** Threading via `wait`/`notify` is error-prone; Kotlin steers you to `synchronized(lock){}`, `java.util.concurrent` locks, or coroutines. - **Reflection has Kotlin-native entry points.** ## How to reach the hidden behavior ```kotlin val s = "hello" val kClass = s::class // KClass<String> (Kotlin reflection) val jClass = s.javaClass // Class<String> (the old getClass()) val lock = Any() synchronized(lock) { /* ... */ } // instead of wait/notify // To literally call Object.wait you must cast: // (lock as Object).wait() ``` - `::class` gives a `KClass`; `.javaClass` gives the JVM `Class`. - `@Synchronized` on a function and `synchronized(x){}` replace `synchronized` methods/blocks. - `@Volatile` replaces the `volatile` field modifier. ## Equality & hashing still come from `Any` Because `Any.equals` is mapped to `Object.equals`, overriding `equals`/`hashCode` in Kotlin produces the same JVM contract Java relies on (e.g. `HashMap` keys). `data class` autogenerates all three. ## Takeaway `Any` = a *curated subset* of `Object`'s surface that is portable and idiomatic; the rest of `Object` is reachable via casts or Kotlin-native APIs but discouraged.
- If `Any` maps to `Object`, why can't I just call `anyValue.wait()`?The Kotlin compiler doesn't expose `wait` on the `Any` type, so it won't resolve. You must cast to `java.lang.Object` first — but idiomatic Kotlin uses `synchronized`/locks/coroutines instead.
- Does `Any` exist on Kotlin/JS or Kotlin/Native?Yes. `Any` is a common-stdlib type present on every platform; only its JVM representation happens to be `java.lang.Object`.
saying these in an interview costs you the question
- Claiming `Any` and `Object` are unrelated at runtime
- Saying you can call `wait`/`notify` directly on an `Any` value
- Not knowing `::class`/`.javaClass` replace `getClass`
- Thinking `Any` has `clone()` or `finalize()`
- Believing `Any` is JVM-only