When using Kotlin on Android etc., there are many people who automatically convert from Java with "Convert Java File to Kotlin File". It actually works, but it's a memo to take it one step further and make better use of Kotlin.
This time you will learn smart cast. Kotlin version: 1.3
You might think that there was a better sample (sweat), but suppose you have some Java and Kotlin mixed code like this:
ResponseModle.java
public class ResponseModle {
public void receiveResponseBody(ItemData data) {
if (data == null) {
return;
}
if (data.getBody() != null) {
ResponseLog.INSTANCE.showLength(data.getBody());
}
// android.text.TextUtils.isEmpty(CharSequence str)
//Can check both null or empty
if (!TextUtils.isEmpty(data.subBody)) {
ResponseLog.INSTANCE.showSubTitle(data.getSubBody());
}
}
ItemData.java
public class ItemData {
private String body = null;
private String subBody = null;
public ItemData(String body, String subBody) {
this.body = body;
this.subBody = subBody;
}
public String getBody() {
return body;
}
public String getSubBody() {
return subBody;
}
}
ResponseLog.kt
object ResponseLog {
public fun showLength(title: String) {
System.out.print(title.length)
}
public fun showSubTitle(subTitle: String) {
System.out.print(subTitle)
}
}
If this is automatically converted and matched to the original shape, it will surely look like this ...
ResponseModle.kt
class ResponseModle {
fun receiveResponceBody(data: ItemData?) {
if (data == null) {
return
}
if (data?.body != null) {
ResponseLog.showLength(data.body)
}
if (!TextUtils.isEmpty(data?.subBody)) {
ResponseLog.showSubTitle(data.subBody!!)
}
}
}
ItemData.kt
data class ItemData(val body: String? = null, val subBody: String? = null)
ResponseLog.kt
object ResponseLog {
public fun showLength(title: String) {
System.out.print(title.length)
}
public fun showSubTitle(subTitle: String) {
System.out.print(subTitle)
}
}
The implementation of the ResponseModle class has become a slightly aggressive implementation. Nullable is unwrapped (data? ...) by judgment even though the null check of ItemData is completed. Only NonNull can be passed as the argument of the method of ResponseLog class. Forced unwrap (... !!) to avoid compilation errors. I don't want to force unwrap because it has already been checked for null.
If you use smart cast, it will compile without forced unwrapping.
ResponseModle.kt
class ResponseModle {
fun receiveResponceBody(data: ItemData?) {
//Smart cast
if (data !is ItemData) return
//Smart cast
if (data.body is String) ResponseLog.showLength(data.body)
// Kotlin1.Smartcast works with isNullOrEmpty from 3
if (!data.subBody.isNullOrEmpty()) ResponseLog.showSubTitle(data.subBody)
}
}
Uses the Elvis operator to avoid forced unwrap ResponseLog.showSubTitle(data.subBody ?: "")
Simple implementation method using let at the time of value assignment
If there is such an implementation
ResponseModle.java
public class ResponseModle {
public void receiveResponseBody(ItemData data) {
String body;
if (data.getBody() == null) {
return;
} else {
body = "OK";
}
ResponseLog.INSTANCE.showLength(body);
}
}
Converting with Convert Java File to Kotlin File
ResponseModle.kt
class ResponseModle {
fun receiveResponceBody(data: ItemData?) {
val body: String
if (data?.body == null) {
return
} else {
body = "OK"
}
ResponseLog.showLength(body);
}
However, it becomes a Java-like implementation. If you use Kotlin with much effort, write simply using let
ResponseModle.kt
class ResponseModle {
fun receiveResponceBody(data: ItemData?) {
val body = data?.body?.let { "OK" } ?: return
ResponseLog.showLength(body);
}
Very simple!
Recommended Posts