Objects & Companion Objects

Kotlin is a modern, concise language that builds the singleton pattern into the language with object , and replaces Java's static members with companion objects.

Learn Objects & Companion Objects in our free Kotlin course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Kotlin course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

By the end of this lesson you'll create singletons, add class-level members with companion objects, and write factory functions.

What You'll Learn in This Lesson

1️⃣ Singletons with object

The object keyword declares a singleton — a single shared instance with no constructor. You access its members directly through its name. It's the built-in, thread-safe way to do the singleton pattern.

Every reference to Database points at the same instance, so its state is shared across your whole program — exactly what a singleton should do.

2️⃣ Companion Objects and Factories

A companion object holds members tied to the class itself — Kotlin's answer to static . It's the natural home for constants and factory functions that build instances (often with a private constructor).

By making the constructor private and exposing User.create , the class fully controls how instances are made — validating and trimming input first.

Your turn. Replace the TODO , then run and compare.

Combine a companion object's constant and factory function with a private constructor.

📋 Quick Reference — Objects

Practice quiz

What does the object keyword create in Kotlin?

  • A new class instance each time
  • An abstract class
  • A singleton with exactly one shared instance
  • A data class

Answer: A singleton with exactly one shared instance. object declares a singleton, created lazily, with one shared instance.

How do you access a member of an object singleton named Database?

  • Directly through its name: Database.add(...)
  • By calling new Database()
  • Database().add(...)
  • Database::add()

Answer: Directly through its name: Database.add(...). Singletons have no constructor; access members via the object's name.

What is a companion object closest to in Java?

  • an inner class
  • a constructor
  • an interface
  • static members

Answer: static members. A companion object holds members tied to the class, like Java's static.

How many companion objects can a class have?

  • Exactly two
  • At most one
  • Unlimited
  • None

Answer: At most one. Each class may have at most one companion object.

How do you call a companion member like create on class User?

  • Through the class name: User.create(...)
  • On an instance: user.create(...)
  • With new User.create()
  • User::Companion()

Answer: Through the class name: User.create(...). Companion members are called via the class name, not an instance.

Why use a factory function instead of a public constructor?

  • It is always faster
  • Constructors cannot take parameters
  • It can have a name, validate input, or return a cached instance
  • It avoids using the class

Answer: It can have a name, validate input, or return a cached instance. Factories add naming, validation, caching, or subtype returns.

What is required for a const val in a companion object?

  • Any runtime-computed value
  • A compile-time constant: a primitive or String literal
  • A nullable type
  • A lambda expression

Answer: A compile-time constant: a primitive or String literal. const val must be a compile-time constant inlined at use sites.

What is the difference between const val and a regular val in a companion?

  • They are identical
  • const val is mutable
  • A regular val must be primitive
  • const val is inlined at compile time; a regular val is computed at runtime

Answer: const val is inlined at compile time; a regular val is computed at runtime. const val needs a compile-time literal; a regular val can be any runtime value.

What enables User.create to call a private constructor in the example?

  • The constructor is actually public
  • The companion object is inside the class, so it can access it
  • Reflection is used
  • Kotlin ignores private on constructors

Answer: The companion object is inside the class, so it can access it. A companion object lives inside the class and can use its private constructor.

When is an object singleton instance created?

  • At program startup always
  • Once per call site
  • Lazily, the first time it is accessed
  • Never until you call new

Answer: Lazily, the first time it is accessed. The singleton is created lazily on first access.