WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Scala · Intermediate · question 38 of 100

What is a value class in Scala, and how does it differ from a regular class?

📕 Buy this interview preparation book: 100 Scala questions & answers — PDF + EPUB for $5

A value class in Scala is a special kind of class that aims to provide the benefits of custom data types without the overhead of additional runtime objects. Value classes can be used to define lightweight and performant classes that wrap a single value. They were introduced in Scala 2.10 as a means to avoid runtime instantiation and garbage collection costs, which can be significant for small objects that are created and discarded frequently.

Value classes differ from regular classes in two main ways:

1. They must extend ‘AnyVal‘ instead of ‘AnyRef‘ (the default base class for Scala classes).

2. They can have only a single, immutable parameter in their primary constructor.

To define a value class, you use the ‘extends AnyVal‘ clause in the class definition and add the ‘val‘ keyword in the primary constructor:

class Meter(val value: Double) extends AnyVal {
  def +(other: Meter): Meter = new Meter(value + other.value)
}

Here, ‘Meter‘ is a value class that wraps a ‘Double‘. It has a single method, ‘+‘, to add two ‘Meter‘ instances. Because ‘Meter‘ is a value class, the addition operation will have minimal overhead compared to directly working with ‘Double‘ values.

Some important restrictions apply to value classes:

1. They cannot have their own ‘equals‘, ‘hashCode‘, or ‘toString‘ methods.

2. They can define only ‘def‘s, not fields or ‘val‘s.

3. They cannot be extended by other classes or value classes.

4. They cannot take type parameters (i.e., they cannot be generic).

The main advantage of value classes is that, under certain circumstances, their instances can be represented at runtime by the underlying values they wrap, which means no instantiation cost and no garbage collection. However, this optimization is not guaranteed, and in some cases instances of value classes may still be created at runtime. The Scala Language Specification provides a detailed list of conditions under which value classes can be "boxed" (i.e., represented as objects).

In contrast, regular classes in Scala, which extend ‘AnyRef‘ by default, always have runtime instantiation and garbage collection costs. If you have a small, simple, and immutable data type that you need to use frequently, you might consider using a value class for performance reasons.

It is also worth to mention Universal Traits. Universal traits are traits that can be extended by both ‘AnyVal‘ (value classes) and ‘AnyRef‘ (regular classes). To define a universal trait, you need to extend ‘Any‘ (the base class for all Scala types) and mark it with a ‘sealed‘ modifier.

sealed trait Measurement extends Any {
  def value: Double
}

Now the value class can extend this universal trait:

class Meter(val value: Double) extends AnyVal with Measurement {
  def +(other: Meter): Meter = new Meter(value + other.value)
}

Keep in mind that mixing in a universal trait only affects the compile-time representation of a value class and does not generally impact its runtime performance.

To summarize, value classes in Scala are a lightweight alternative to regular classes that can provide better performance characteristics for specific use cases of small, simple, and immutable data types. They have some restrictions and trade-offs compared to regular classes, but can be beneficial when used appropriately.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Scala interview — then scores it.
📞 Practice Scala — free 15 min
📕 Buy this interview preparation book: 100 Scala questions & answers — PDF + EPUB for $5

All 100 Scala questions · All topics