Kotlin – Phiên bản nâng cấp của Java
Bài đăng này đã không được cập nhật trong 7 năm
- Java là một ngôn ngữ lập trình vô cùng mạnh mẽ nhưng nó cũng có điểm yếu của mình. Vì thế mà tôi khuyên các bạn nên đọc qua quyển Effective Java của Joshua Bloch’s. Đó là một quyển hướng dẫn toàn thư về Java code cũng như liệt kê về lỗi về coding cũng như cách khắc phục chúng. Bao gồm 78 mục , cho người đọc nhiều kiến thức quí giá về Java.
- Các ngôn ngữ lập trình mới có một ưu điểm vượt trội là phân tích những điểm yếu của chúng để tự cải thiện bản thân mình. Jetbrains , một công ty về công nghệ khá nổi tiếng nhờ tạo ra nhiều IDEs được cộng đồng nhiệt liệt ủng hộ, đã đưa ra quyết định tạo ra ngôn ngữ lập trình Kotlin vào năm 2010 nhằm phục vụ cho quá trình phát triển project của riêng mình. Mục tiêu đươc đề ra cho Kotlin là trở nên chính xác cũng như dễ hiểu hơn trong khi loại bỏ đi những nhược điểm của Java. Bởi tất cả IDEs của Jetbrain đều dùng Java, thế nên họ cần một ngôn ngữ mới nhưng vẫn có khả năng hoạt động được với Java. Mặt khác, các Java developer cũng dễ dàng chuyển qua xài Kotlin hơn.Với Kotlin, Jetbrains kì vọng tạo ra một phiên bản Java tốt hơn.
Sau khi đọc lại quyển “Effective Java”, tôi nhận ra có khá nhiều thứ không còn áp dụng được với Kotlin, vì thế mà với bài viết này tôi sẽ phân tích rõ ràng về cách dùng Kotlin. Builders không còn cần thiết với Kotlin’s default value
- Khi bạn có quá nhiều parameters cho một constructor trong Java, code sẽ trở nên rất khó đọc cũng như nhiều lỗi. Theo cuốn “effective Jave”, “Item” thứ 2, chỉ cách ta có thể dùng Builder Pattern một cách hiệu quả nhất. Với ví dụ một object có nội dung nói về fact các giá trị dinh dưỡng, chúng ta sẽ cần 2 required paramenters (servingSize, servings) và 4 optional parameters ( calories, fat, sodium, carbohydrates):
public class JavaNutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public static class Builder {
// Required parameters
private final int servingSize;
private final int servings;
// Optional parameters - initialized to default values
private int calories = 0;
private int fat = 0;
private int carbohydrate = 0;
private int sodium = 0;
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val)
{ calories = val; return this; }
public Builder fat(int val)
{ fat = val; return this; }
public Builder carbohydrate(int val)
{ carbohydrate = val; return this; }
public Builder sodium(int val)
{ sodium = val; return this; }
public JavaNutritionFacts build() {
return new JavaNutritionFacts(this);
}
}
private JavaNutritionFacts(Builder builder) {
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
Ngay lập tức, một object trong Java sẽ cho kết quả như sau:
final JavaNutritionFacts cocaCola = new JavaNutritionFacts.Builder(240,8)
.calories(100)
.sodium(35)
.carbohydrate(27)
.build();
- Ngược lại với Kotlin thì lại không hề cần một builder pattern bởi nó có tính nặng gọi là default parameters, cho phép bạn đặt default values cho từng optional constructor argument:
class KotlinNutritionFacts(
private val servingSize: Int,
private val servings: Int,
private val calories: Int = 0,
private val fat: Int = 0,
private val sodium: Int = 0,
private val carbohydrates: Int = 0)
- Tạo ra một object trong Kotlin sẽ giống như thế này:
val cocaCola = KotlinNutritionFacts(240,8,
calories = 100,
sodium = 35,
carbohydrates = 27)
- Cũng như Java, object tạo tại Kontlin cũng là immutable.
- Bạn có thể thấy số dòng code đã giảm từ 47 trong Java xuống còn 7 trong Kotlin, kết quả là tốt độ xử lý nhanh lên mấy lần. Tip: nếu bạn muốn tạo ra KotlinNutrition object trong Java, thì vẫn được thôi, nhưng nó đòi hỏi bạn phải đưa ra value cho từng optional parameter. May thay, là nếu bạn thêm JvmOverloads annotation thì sẽ cho ra được các constructors. Tất nhiên là để dùng được chúng thì bạn cũng sẽ phải thêm vào keyword constructor :
class KotlinNutritionFacts @JvmOverloads constructor(
private val servingSize: Int,
private val servings: Int,
private val calories: Int = 0,
private val fat: Int = 0,
private val sodium: Int = 0,
private val carbohydrates: Int = 0)
Dễ dàng trong việc tạo ra Singleton
- Chúng ta luôn muốn tạo ra một Java object nhưng lại có khả năng hoạt động như singleton. Với code sau đây sẽ giúp bạn làm được việc trên:
public class JavaElvis {
private static JavaElvis instance;
private JavaElvis() {}
public static JavaElvis getInstance() {
if (instance == null) {
instance = new JavaElvis();
}
return instance;
}
public void leaveTheBuilding() {
}
}
- Kotlin lại có sẵn object declaration giúp cho object hoạt động như singleton luôn:
object KotlinElvis {
fun leaveTheBuilding() {}
}
Equals() và HashCode()
-
Đối với functional programming cũng như giữ code đơn giản thì việc dùng immutable value objects là điều không cần phải bàn cãi. immutable ở đây ám chỉ sự không thay đổi. Nói cách khác, class luôn nên là immutable trừ khi bạn bắt buộc phải làm ngược lại. Thế nhưng công việc tạo Immutable value object trong Java rất là chán luôn bởi cứ thêm equals() và hashCode() funtion vào cho từng object một. Chưa kể khi override equals() còn phải bảo đảm contracts luôn được tính nhất quán, đối xứng, etc…. nghe phức tạp như toán học vậy đó.
-
Trong Kotlin, các bạn chỉ cần dùng Data Classes, khi đó compiler sẽ tự động làm thay mọi việc cho bạn. Tất cả yêu cầu là bạn type data` vào trước class.
Tip: Gần đây, AutoValue cho Java trở nên vô cùng nổi tiếng. Library có khả năng tạo ra immutable value classes cho Java 1.6+.
Properties thay vì fields
-
Hẳn các bạn khi dùng tới Java cũng luôn được chỉ rằng nên dùng accessor thay cho public field trong public class. Bởi nếu không thì bạn sẽ gặp phải nhiều vấn đề bởi field khi đó sẽ có thể vào trực tiếp và mất tính linh hoạt. Nói cách khác khi bạn thay đổi đại diện nội bộ của class (internal representation) thì nó còn ảnh hưởng lên cả public API của nó. Như vậy, bạn cũng sẽ chẳng thể nào đưa ra giới hạn cho value của một field (vd như độ tuổi từ 18 trở lên chẳng hạn). Đó là nguyên nhân vì sao mà chúng ta luôn cần tới verbose default getters và setter trong Java.
-
Vấn đề trên được giải quyết với Kotin nhờ vào việc sử dụng properties với auto-generated default getters và setters thay vì field.
class KotlinPerson {
var name: String? = null
var age: Int? = null
}
- Nói cách khác, bạn có thể truy cập vào các properties như public fields trong Java với person.namehoặc person.age., không những thế mà ta còn thêm và custom getters và setters mà không lo API của class bị thay đổi.
class KotlinPerson {
var name: String? = null
var age: Int? = null
set(value) {
if (value in 0..120){
field = value
} else{
throw IllegalArgumentException()
}
}
}
-
Tóm lại là với Kotlin properties thì ta sẽ có class với độ chuẩn xác cao mà lại cực kì linh hoạt.
-
Annotations được đưa vào Java từ bản cập nhật 1.5. trong đó có Override. Khi vào làm trong Java, bạn sẽ nhận ra rằng mình nên luôn dùng override để tránh dính phải những bug nguy hiểm. Lúc đó, complier sẽ thông báo là có error khi bạn overriding một method từ superclass, thế nhưng thật ra là không phải đâu, miễn là bạn vẫn sử dụng Override annotation thì mọi chuyện đều ổn cả.
-
Trong Kotlin thì Override annotation còn được xem là keyword chính luôn. Thế nên khỏi phải lo về vụ gặp phải mấy cái bug hiểm ác. Kotlin sẽ giúp bạn code nhẹ nhàng hơn rất nhiều. Link : https://kotlinlang.org/docs/reference/classes.html#overriding-members
All rights reserved