Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Java Records vs. Kotlin Data Classes

Java Records vs. Kotlin Data Classes

Video: https://youtu.be/KXEJ4tgNzwk?si=G620QBh3r4W5HQf0

Do you think Java needs to catch up with modern programming trends, especially compared with Kotlin?

In this video, we will see one hidden feature that might change our view of this topic.

Java Records and Kotlin Data Classes help developers create simple data-holding classes efficiently.

Java introduced Records in Java 14.

Kotlin introduced Data Classes in version 1.1.

Both aimed at simplifying coding structures in their respective languages.

With the possibilities in Kotlin Data Classes, we feel that Java is always playing catch-up with Kotlin, and that is partially true in terms of syntax and some features.

As developers, we need to understand what is happening at least one level from where we usually operate.

Let's explore some concepts a bit further to understand them, which are not necessarily exposed when we use Java Records and Kotlin Data Classes alone.

Carlos Chacin

July 09, 2024
Tweet

More Decks by Carlos Chacin

Other Decks in Programming

Transcript

  1. record Point( int x, int y) { } data class

    Point( val x: Int, val y: Int)
  2. record Point( int x, int y) { } data class

    Point( val x: Int, val y: Int)
  3. record Point( int x, int y) { } data class

    Point( val x: Int, val y: Int)
  4. record Point( int x, int y) { } @JvmRecord data

    class Point( val x: Int, val y: Int)
  5. record Point( int x, int y) { } @JvmRecord data

    class Point( val x: Int, val y: Int)
  6. record Point( int x, int y) { } @JvmRecord data

    class Point( val x: Int, val y: Int)
  7. record Point( int x, int y) { } var point

    = new Point(10, 20); // (10, 20) @JvmRecord data class Point( val x: Int, val y: Int) val point = Point(10, 20) // (10, 20)
  8. record Point( int x, int y) { } var point

    = new Point(10, 20); // (10, 20) @JvmRecord data class Point( val x: Int, val y: Int) val point = Point(10, 20) // (10, 20) val newPoint = point.copy(20) // (20, 20)
  9. record Point( int x, int y) { } var point

    = new Point(10, 20); // (10, 20) @JvmRecord data class Point( val x: Int, val y: Int) val point = Point(10, 20) // (10, 20) val newPoint = point.copy(20) // (20, 20) With Expressions (JEP 468)
  10. record Point( int x, int y) { } var point

    = new Point(10, 20); // (10, 20) var newPoint = point with { x = 20 } // (20, 20) @JvmRecord data class Point( val x: Int, val y: Int) val point = Point(10, 20) // (10, 20) val newPoint = point.copy(20) // (20, 20) With Expressions (JEP 468)
  11. public String toString(); Code: 0: new #34 / / class

    StringBuilder 3: dup 4: invokespecial #35 / / Method StringBuilder 7: ldc #37 / / String Point(x= 9: invokevirtual #41 / / Method StringBuilder 12: aload_0 13: getfield #13 // Field x:I 16: invokevirtual #44 // Method StringBuilde 19: ldc #46 // String , y= 21: invokevirtual #41 // Method StringBuilde 24: aload_0 25: getfield #16 // Field y:I 28: invokevirtual #44 // Method StringBuilde 31: bipush 41 33: invokevirtual #49 // Method StringBuilde 36: invokevirtual #51 // Method StringBuilde 39: areturn @JvmRecord data class Point( val x: Int, val y: Int)
  12. public String toString(); Code: 0: new #34 / / class

    StringBuilder 3: dup 4: invokespecial #35 / / Method StringBuilder 7: ldc #37 / / String Point(x= 9: invokevirtual #41 / / Method StringBuilder 12: aload_0 13: getfield #13 // Field x:I 16: invokevirtual #44 // Method StringBuilde 19: ldc #46 // String , y= 21: invokevirtual #41 // Method StringBuilde 24: aload_0 25: getfield #16 // Field y:I 28: invokevirtual #44 // Method StringBuilde 31: bipush 41 33: invokevirtual #49 // Method StringBuilde 36: invokevirtual #51 // Method StringBuilde 39: areturn @JvmRecord data class Point( val x: Int, val y: Int)
  13. public int hashCode(); Code: 0: aload_0 1: getfield #13 /

    / Field x:I 4: invokestatic #57 / / Method java/lang/Int 7: istore_1 8: iload_1 9: bipush 31 11: imul 12: aload_0 13: getfield #16 // Field y:I 16: invokestatic #57 // Method java/lang/In 19: iadd 20: istore_1 21: iload_1 22: ireturn @JvmRecord data class Point( val x: Int, val y: Int)
  14. public int hashCode(); Code: 0: aload_0 1: getfield #13 /

    / Field x:I 4: invokestatic #57 / / Method java/lang/Int 7: istore_1 8: iload_1 9: bipush 31 11: imul 12: aload_0 13: getfield #16 // Field y:I 16: invokestatic #57 // Method java/lang/In 19: iadd 20: istore_1 21: iload_1 22: ireturn @JvmRecord data class Point( val x: Int, val y: Int)
  15. public boolean equals(Object); Code: 0: aload_0 1: aload_1 2: if_acmpne

    7 5: iconst_1 6: ireturn 7: aload_1 8: instanceof #2 // class org/acme/Point 11: ifne 16 14: iconst_0 15: ireturn 16: aload_1 17: checkcast #2 // class org/acme/Point 20: astore_2 21: aload_0 22: getfield #13 // Field x:I 25: aload_2 26: getfield #13 // Field x:I 29: if_icmpeq 34 32: iconst_0 33: ireturn 34: aload_0 35: getfield #16 // Field y:I 38: aload_2 39: getfield #16 // Field y:I 42: if_icmpeq 47 45: iconst_0 46: ireturn 47: iconst_1 48: ireturn @JvmRecord data class Point( val x: Int, val y: Int)
  16. public boolean equals(Object); Code: 0: aload_0 1: aload_1 2: if_acmpne

    7 5: iconst_1 6: ireturn 7: aload_1 8: instanceof #2 // class org/acme/Point 11: ifne 16 14: iconst_0 15: ireturn 16: aload_1 17: checkcast #2 // class org/acme/Point 20: astore_2 21: aload_0 22: getfield #13 // Field x:I 25: aload_2 26: getfield #13 // Field x:I 29: if_icmpeq 34 32: iconst_0 33: ireturn 34: aload_0 35: getfield #16 // Field y:I 38: aload_2 39: getfield #16 // Field y:I 42: if_icmpeq 47 45: iconst_0 46: ireturn 47: iconst_1 48: ireturn @JvmRecord data class Point( val x: Int, val y: Int)
  17. record Point( int x, int y) { } public String

    toString(); public int hashCode(); public boolean equals(Object);
  18. record Point( int x, int y) { } public String

    toString(); public int hashCode(); public boolean equals(Object);
  19. record Point( int x, int y) { } public String

    toString(); public int hashCode(); public boolean equals(Object);
  20. record Point( int x, int y) { } public String

    toString(); public int hashCode(); public boolean equals(Object);
  21. public final String toString(); Code: 0: aload_0 1: invokedynamic #19,

    0 6: areturn record Point( int x, int y) { }
  22. public final String toString(); Code: 0: aload_0 1: invokedynamic #19,

    0 6: areturn record Point( int x, int y) { }
  23. record Point( int x, int y) { } public final

    int hashCode(); Code: 0: aload_0 1: invokedynamic #23, 0 6: ireturn
  24. record Point( int x, int y) { } public final

    int hashCode(); Code: 0: aload_0 1: invokedynamic #23, 0 6: ireturn
  25. record Point( int x, int y) { } public final

    boolean equals(Obje Code: 0: aload_0 1: aload_1 2: invokedynamic #27, 0 7: ireturn
  26. record Point( int x, int y) { } public final

    boolean equals(Obje Code: 0: aload_0 1: aload_1 2: invokedynamic #27, 0 7: ireturn
  27. Java Records can take advantage of the JVM’s implementation and

    future improvements for the toString, equals & hashCode methods without recompiling.