Hi everyone, I am DHL. ByteCode, focus on the latest technology to share original articles, involving Kotlin, Jetpack, algorithm animation, data structure, system source code, LeetCode/point Offer/multithreading/domestic and foreign large factory algorithm problems and so on.

In a previous article, Kotlin 1.5 announced a blockbuster feature called Value Class, which is a very useful feature that improves code readability while also improving performance as the compiler optimizes it at a deeper level. Mainly contains the following content, have not seen partners can go to check.

  • inline classvalue classWhat’s the difference?
  • value classCannot be inherited, but can implement interfaces
  • When the object passed is empty,value classThe inline effect will be lost
  • value classIt is prohibited to use= = =You can use= =

Today, this article mainly introduces the difference between value class and data class, which may be a few details that are easily overlooked when doing business development at ordinary times. In this article, you will learn the following.

  • What is thevalue class ?
  • What is thedata class ?
  • value classdata classThe difference between
    • value classIt takes up less memory and is more efficient
    • value classExecution efficiency ratiodata classHow much faster
    • value classThere is nocopy()methods
    • value classA constructor can take only one argument
    • value classWhy can’t I rewrite itequals()hashcode()methods
    • value classdata classCan’t be inherited

What is a value class

The value class represents an inline class that requires passing in a parameter to the main constructor and is decorated with val. When compiled into Java code, it is replaced with the value passed in, as shown below.

@JvmInline
value class User(val name: String)

fun login(user: User?).: String = user? .name ?:""

fun testInline(a) {
    println(login(User("DHL")))}// The compiled code
public static final String login_js0Jwf8/* $FF was: login-js0Jwf8*/(@Nullable String user) {
    / /...
  return var10000;
}

public static final void testInline() {
    String var0 = login-js0Jwf8("DHL");
    System.out.println(var0);
}
Copy the code

As you can see, the compiled Java code does not create additional objects, but instead replaces the object User created in Kotlin with the value DHL passed in.

What is a Data class

A data class represents a data class, and the compiler uses the parameters declared by the main constructor, The automatic generation of template methods such as Quals (), hashCode(), toString(), componentN(), copy(), setXXX(), getXXX(), and so on frees us from repetitive labor and focuses on the implementation of the core business.

data class User(val name: String)

// After compiling
public final class User {
   private final String name;
   public final String getName() { return this.name; }...public final String component1() { return this.name; }
   public final User copy(@NotNull String name) { returnnew User(name); }... }Copy the code

The difference between value class and Data class

The Value Class consumes less memory and is more efficient

To ensure that the same logic applies everywhere, validation of parameters in the Model is usually wrapped in the current model, such as checking if the User name is null in a Data Class User.

data class User(var name: String? = null) {
    init {
        requireNotNull(name) { "name is not null"}}}Copy the code

Each time we create a User object, we allocate the object in the heap, which takes up more memory and makes our code execute less efficiently. The object creation process is very slow. You go through two processes: the class loading process and the object creation process.

  • Class loading process

    • Determines whether the class has been initialized, and if not, the class loading process is performed
    • The loading process of a class: the loading, validation, preparation, parsing, initialization phases, and so on, are then executed<clinit>()Method, initialize static variables, execute static code blocks, and so on
  • Object creation process

    • If the class is already initialized, the object creation process is performed directly
    • Object creation process: create a block of heap memory, allocate an address to the open space, perform initialization, will execute<init>()Method to initialize a normal variable and call a normal code block

Value Calss helps us solve these problems by making code execution more efficient and using less memory. This is all thanks to the Kotlin compiler’s extensive optimization of it.

@JvmInline
value class User(val name: String)
fun login(user: User?).: String = user? .name ?:""
println(login(User("DHL")))

// The compiled code
String var0 = login-js0Jwf8("DHL");
System.out.println(var0);
Copy the code

As you can see, when we instantiate User, instead of allocating objects in the heap, we replace the User argument passed to the method login() with the value passed in, DHL.

How much faster a Value class executes than a Data class

Let’s use an example to see how much faster a Value class is than a data class, as shown below.

data class User1(val name: String)
fun printDataClass(user: User1) {}

@JvmInline
value class User2(val name: String)
fun printValueClass(user: User2) {}

@OptIn(ExperimentalTime::class)
fun main(a) {
    // data class
    val measureDataClass = measureTime {
        repeat(100) {
            User1("DHL")
        }
    }
    println("measure data class time  ${measureDataClass.toDouble(TimeUnit.MILLISECONDS)} ms")

    // value class
    val measureRunValueClass = measureTime {
        repeat(100) {
            User2("DHL")
        }
    }
    println("measure value class time ${measureRunValueClass.toDouble(TimeUnit.MILLISECONDS)} ms")}Copy the code

The only difference is that User1 is declared with data class and User2 with value class. The final execution time is shown below.

measure data class time  6.790241 ms
measure value class time 0.832866 ms
Copy the code

The value class performs much more efficiently than the Data class. When there’s a lot of data, the gap gets bigger and bigger.

Value class has no copy () method

Like data class, value calss can have init function or internal function, which is convenient for us to encapsulate business logic.

But value calss does not generate a copy() method, whereas data Class compilation generates a copy() method, as shown below.

data class User(val name: String, val pwd: String)

// After compiling
public final class User {...@NotNull
   public final User copy(@NotNull String name, @NotNull String pwd) {
      returnnew User(name, pwd); }... }Copy the code

This also means that by creating a copy of the object instance with Data calss, we don’t need to rewrite all the parameters and can specify the parameters that need to be changed.

user = user.copy(name = "hi-dhl")
Copy the code

Value calss can only create objects through constructors that specify all parameters.

The Value class constructor can take only one argument

At the moment, a value class can only take one parameter in the constructor, and it needs to be modified with val, whereas data CalSS supports adding multiple parameters in the constructor. Parameters can be declared with val or var. In the near future, however, Kotlin will support adding multiple parameters to the value class constructor, as shown in the figure below.

Neither Value class nor Data class can be inherited

Because value class and Data class are compiled with fianl modifiers, they cannot be inherited, nor can they be inherited from other classes, as shown in the figure below.

Value class cannot override equals (), hashCode () methods

Value class cannot override equals() and HashCode () methods compared to data class, as shown in the figure below.

The equals() method is used to compare the contents of two arguments. For the difference between Kotlin’s == and === and eauals, see Koltin’s == and === and eauals in my other article.

Because the value class constructor can only pass in one argument and must be decorated with val, there are no scenarios where two identical arguments need to be compared, so Kotlin won’t let the equals() and hashcode() methods be overridden.


A “like” would be the biggest encouragement if it helps

More code, more articles

Welcome to the public account: ByteCode, continue to share the latest technology



Finally, recommend long-term update and maintenance projects:

  • Personal blog, will all articles classification, welcome to check hi-dhl.com

  • KtKit compact and practical, written in Kotlin language tool library, welcome to check KtKit

  • Androidx-jetpack-practice androidX-Jetpack-practice androidX-Jetpack-practice androidX-Jetpack-Practice androidX-Jetpack-Practice

  • LeetCode/multiple thread solution, language Java and Kotlin, including a variety of solutions, problem solving ideas, time complexity, spatial complexity analysis

  • Job interview with major companies at home and abroad
  • LeetCode: Read online

Must-read articles these days

  • Launching a website in 1 minute – no domain name, no server – has never been easier
  • Box-sizing: border-box! Important; word-wrap: break-word! Important; “> < span style =” max-width: 100%
  • Android 12 is here, did your App crash?
  • Kotlin announced a blockbuster feature
  • Google has announced the abandonment of the LiveData.observe method
  • One detail to note when using Kotlin
  • Kotlin code affecting Performance (1)
  • Jetpack Splashscreen parsing | power generation IT migrant workers get twice the result with half the effort
  • Kotlin’s Technique and Analysis (3)
  • Uncover the == and === in Kotlin
  • The Kotlin hermetic class evolved