Kotlin vs Java: Sự khác biệt


Java có lẽ là ngôn ngữ đầu tiên khi bạn muốn phát triển một ứng dụng Android. Tuy nhiên có một số ngôn ngữ khác cũng có thể phát triển ứng dụng Android như C#, C/C++.

Từ Android Studio 3.0 preview, đã tích hợp Kotlin rất dễ dàng. Trong bài viết này, chúng ta sẽ tìm kiếm tất cả những tính năng khác nhau chính giữa Java và Kotlin, bao gồm một vài tính năng bạn sẽ phải hi sinh (sacrificing) nếu bạn chuyển sang làm với Kotlin

Kotlin cung cấp một cấu trúc code gọn hơn - Không cần sử dụng findViewByIds
Nếu bạn so sánh một class Java và một class Kotlin với cùng một công việc, bạn sẽ thấy Kotlin class nhìn chung sẽ ngắn ngọn hơn rất nhiều. Có một nơi mà Kotlin có thể lược giảm rất nhiều các đoạn mã code: findViewByIds.

Kotlin Android Extensions cho phép bạn import một tham chiếu từ một View tới file Activity, bạn sẽ có thể làm việc với View đó như là một phần của Activity. Kết quả bạn sẽ không bao giờ cần phải viết findViewByIds một lần nào nữa.
Trước khi bạn có thể sử dụng những extensions này, bạn cần thêm một plugin tới file build.gradle (plugin áp dụng: 'kotlin-android-extensions') nhưng sau khi bạn đã sẵn sàng bắt đầu importing Views, ví dụ như nếu file activity_main.xml của bạn bao gồm TextView với ID textView, sau đó bạn sẽ phải thêm dòng dưới đây tới Activity của bạn:

import kotlinx.android.synthetic.main.activity_main.textView

Bạn có thể truy cập TextView này sử dụng chỉ với ID của nó:

textView.setText("Hello World")

Điều này rút gọn hơn khi viết bằng Java:

TextView text = (TextView) findViewById(R.id.textView); text.setText("Hello World");

Kotlin: null được khai báo an toàn 
NullPointerExceptions là nỗi thất vọng lớn trong phát triển bằng Java. Java cho phép bạn đăng ký một đối tượng có giá trị null, nhưng khi bạn sử dụng đối tượng null đó, bạn sẽ gặp phải một NullPointerException.

Trong Kotlin, tất cả được mặc định là không null (non - nullable). Nếu bạn cố tình chỉ định null trong code Kotlin, chương trình sẽ compile lỗi, giống như 2 dòng dưới đây:

val name: String = null

fun getName() : String = null

Nếu bạn thực sự muốn gán giá trị null tới một biến trong Kotlin, bạn sẽ phải thêm dấú ? sau kiểu dữ liêu :

val number: Int? = null

Điều này làm lỗi NullPointerException hầu như không còn được gặp trong Kotlin nữa

Các hàm mở rộng (Extension functions)
Kotlin cho phép lập trình viên khả năng mở rộng một class với những tính năng mới.
Bạn tạo một hàm extension bằng tiền tố (prefixing) tên của class bạn muốn mở rộng (ví dụ 'String') tới tên của hàm bạn muốn tạo:

fun String.styleString(): String {
// Style the string and then return it//
}

Sau đó bạn có thể gọi hàm này trong khởi tạo của một class kế thừa thông qua ký hiệu .

myString.styleString()
 
Coroutines
Khi bạn thực hiện một tác vụ lâu dài, như là network I/O hoặc công việc đòi hỏi nhiều CPU, thread đang được gọi sẽ bị block cho đến khi tác vụ thực hiện xong. Vì Android mặc định là single-threaded, main thread của bạn sẽ bị block và giao diện sẽ bị đóng băng và nó sẽ không phản hồi cho đến khi thao tác hoàn tất.
Trong Java, giải pháp được đưa ra là tạo một background-thread, nhưng việc quản lý nhiều thread cùng lúc là phức tạp và việc tạo một luồng mới là mộ hoạt động tốn kém.
Trong Kotlin bạn vẫn có thể tạo một thread khác, nhưng có một các khác là sử dụng Coroutines.

Kotlin không có kiểm tra exceptions
Điều này có thể là thiếu sót so với Java tuỳ theo ý kiến của bạn

Kotlin Property Delegation 
 Kotlin hỗ trợ 'composition over inheritance' design pattern. Class delegation của Kotlin là một thay thế của kế thừa để làm nó có thể sử dụng đa kế thừa, ngăn chặn việc duplication code. Ví dụ như bạn cần tái sử dụng đoạn code getters và setters, chúng ta có thể làm như sau:

class Delegate {
    operator fun getValue(...)
...
...
...
    }

    operator fun setValue(...)
...
...
...
    }
}
Sau đó, khi bạn tạo một property, bạn có thể khai báo hàm getter và setter cho property cụ thể được xử lý trong một class khác :
 
class MyClass {
var property: String by Delegate()
}
 
Data class 
Trong Java bạn sẽ phải viết rất nhiều đoạn mã soạn sẵn cho các lớp này, mặc dù bản thân các lớp này có rất ít tính năng. Thông thường, bạn sẽ cần định nghĩa một hàm khởi tạo, trường để lưu trữ dữ liệu, các hàm getter và setter cho mỗi trường, thêm cả hashCode(), equals() và hàm toString()
Trong kotlin, nếu bạn thêm keyword 'data' trong định nghĩa class của bạn, trình biên dịch sẽ thực hiện tất cả các công việc đó cho bạn, bao gồm generating tất cả thứ cần thiết getter và setter:

data class Date(var month:String, var day: Int)

Smart casts
Trong Java, bạn phải check kiểu và sau đó trong một tình huống cụ thể , để ép kiểu một object cần thực sự clear kiểu của object.
Việc ép kiểu trong Kotlin là thông minh hơn:
 
if (hello is String) {
    printString(hello)
}
 
Hỗ trợ cho constructors
 Không giống như trong Java, một class Kotlin có thể có một hàm khởi tạo chính, một hoặc nhiều hàm khởi tạo phụ, cái mà bạn có thể thêm chúng vào khởi tạo class của bạn:

class MainActivity constructor(firstName: String) {
}

Không hỡ trợ ngầm chuyển đổi mở rộng 
Trong Java khi bạn muốn gán giá trị kiểu Byte tới kiểu Int, sẽ được hỗ trợ ngầm, nhưng trong Kotlin thì không. Bạn sẽ cần phải chuyển đổi rõ ràng.

Chú thích khi xử lý thư viện với Kotlin
Kotlin hỗ trợ toàn bộ các thư viện của Java, mặc dù có các thư viện đã có phần mở rộng cho Kotlin:
Nếu bạn muốn sử dụng thư viện Java bạn phải sử dụng plugin kotlin-kapt

//Apply the plugin//
apply plugin: 'kotlin-kapt'

//Add the respective dependencies using the kapt configuration//

dependencies {
    kapt "com.google.dagger:dagger-compiler:$dagger-version"
...
...
...
}

Comments