# Inline value classes

[Good wrap up article](https://kt.academy/article/ek-value-classes) (with great example of the usage)

[Thoughts from official Kotlin team](https://github.com/Kotlin/KEEP/blob/master/notes/value-classes.md#inline-classes-are-user-defined-value-classes)

We can use inline value classes to make a wrapper around some type with :exclamation: **no performance overhead** (*Item 47: Avoid unnecessary object creation*). Two especially popular uses of inline value classes are:

* To indicate a unit of measure.
* To use types to protect users from value misuse.

```kotlin
@JvmInline
value class Name(private val value: String) {
    fun greet() {
        print("Hello, I am $value")
    }
}

// Code
val name: Name = Name("Marcin")

// During compilation replaced with code similar to:
// Such a class will be replaced with the value it holds whenever possible:
val name: String = "Marcin"

//-------------------

// Code
name.greet()

// During compilation replaced with code similar to: STATIC methods
Name.`greet-impl`(name)
```

## JPA Entities

In SQL databases, we often identify elements by their IDs, which are all just numbers. For instance, let’s say that you have a student’s grade in a system, which will probably need to reference the id of a student, teacher, school, etc:

```java
@Entity(tableName = "grades")
class Grades(
    @ColumnInfo(name = "studentId")
    val studentId: Int,
    @ColumnInfo(name = "teacherId")
    val teacherId: Int,
    @ColumnInfo(name = "schoolId")
    val schoolId: Int,
    // ...
)
```

The problem is that it is really easy to later misuse all these ids, and the type system does not protect us because they are all of type `Int`. The solution is to wrap all these integers into separate inline value classes:

```java
@JvmInline
value class StudentId(val studentId: Int)

@JvmInline
value class TeacherId(val teacherId: Int)

@JvmInline
value class SchoolId(val studentId: Int)

@Entity(tableName = "grades")
class Grades(
    @ColumnInfo(name = "studentId")
    val studentId: StudentId,
    @ColumnInfo(name = "teacherId")
    val teacherId: TeacherId,
    @ColumnInfo(name = "schoolId")
    val schoolId: SchoolId,
    // ...
)
```

Now those id uses will be safe and the database will be generated correctly because all these types will be replaced with `Int` anyway during compilation. This way, inline value classes allow us to introduce types where they were not allowed before; thanks to this, we have safer code with no performance overhead.
