我们大家都知道Data Classes
会自动帮我们生成get,set方法,减少代码编写量,更轻量级别的实体类
简单的知识点呢我们就不详细介绍了大家可以查看官网:Data Classes
这里我们介绍的是不为人知的一些隐秘操作
我们声明一个类BaseMessage,这个类是我们常用语接受接口字段的一个Base实体
data class BaseMessage(val message: String, val code: Int)
这里我们code使用Int对象类型,且不为空
这就要说起一个美妙的故事了,我们接口在定义接口文档时是code
没错,但是在实际开发中他把code
命名成了retCode
,按道理这时我们是使小写的code
时,应该报错kotlin的空指针.但实际上并没有发生.
而接口定义code 为 0 时是成功的,在接口无论返回任何结果的时候 我客服端的操作都是成功的
抱着怀疑的猜想我怀疑Data Classes做了一些不为人知的勾当
首先根据我们的结果来判断我感觉code像是被附了默认值0,但是我们用的Int是个对象类型而不是Java中的int
话说了这么多 ,我们看下到底BaseMessage转换成java到底是什么?
package com.secoo.goodslist.mvp.ui.holder;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@Metadata(
mv = {1, 1, 16},
bv = {1, 0, 3},
k = 1,
d1 = {"\u0000 \n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0000\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\b\n\u0002\b\t\n\u0002\u0010\u000b\n\u0002\b\u0004\b\u0086\b\u0018\u00002\u00020\u0001B\u0015\u0012\u0006\u0010\u0002\u001a\u00020\u0003\u0012\u0006\u0010\u0004\u001a\u00020\u0005¢\u0006\u0002\u0010\u0006J\t\u0010\u000b\u001a\u00020\u0003HÆ\u0003J\t\u0010\f\u001a\u00020\u0005HÆ\u0003J\u001d\u0010\r\u001a\u00020\u00002\b\b\u0002\u0010\u0002\u001a\u00020\u00032\b\b\u0002\u0010\u0004\u001a\u00020\u0005HÆ\u0001J\u0013\u0010\u000e\u001a\u00020\u000f2\b\u0010\u0010\u001a\u0004\u0018\u00010\u0001HÖ\u0003J\t\u0010\u0011\u001a\u00020\u0005HÖ\u0001J\t\u0010\u0012\u001a\u00020\u0003HÖ\u0001R\u0011\u0010\u0004\u001a\u00020\u0005¢\u0006\b\n\u0000\u001a\u0004\b\u0007\u0010\bR\u0011\u0010\u0002\u001a\u00020\u0003¢\u0006\b\n\u0000\u001a\u0004\b\t\u0010\n¨\u0006\u0013"},
d2 = {"Lcom/secoo/goodslist/mvp/ui/holder/BaseMessage;", "", "message", "", "code", "", "(Ljava/lang/String;I)V", "getCode", "()I", "getMessage", "()Ljava/lang/String;", "component1", "component2", "copy", "equals", "", "other", "hashCode", "toString", "SecooComponentMaster.module-goodslist"}
)
public final class BaseMessage {
@NotNull
private final String message;
private final int code;
@NotNull
public final String getMessage() {
return this.message;
}
public final int getCode() {
return this.code;
}
public BaseMessage(@NotNull String message, int code) {
Intrinsics.checkParameterIsNotNull(message, "message");
super();
this.message = message;
this.code = code;
}
@NotNull
public final String component1() {
return this.message;
}
public final int component2() {
return this.code;
}
@NotNull
public final BaseMessage copy(@NotNull String message, int code) {
Intrinsics.checkParameterIsNotNull(message, "message");
return new BaseMessage(message, code);
}
// $FF: synthetic method
public static BaseMessage copy$default(BaseMessage var0, String var1, int var2, int var3, Object var4) {
if ((var3 & 1) != 0) {
var1 = var0.message;
}
if ((var3 & 2) != 0) {
var2 = var0.code;
}
return var0.copy(var1, var2);
}
@NotNull
public String toString() {
return "BaseMessage(message=" + this.message + ", code=" + this.code + ")";
}
public int hashCode() {
String var10000 = this.message;
return (var10000 != null ? var10000.hashCode() : 0) * 31 + this.code;
}
public boolean equals(@Nullable Object var1) {
if (this != var1) {
if (var1 instanceof BaseMessage) {
BaseMessage var2 = (BaseMessage)var1;
if (Intrinsics.areEqual(this.message, var2.message) && this.code == var2.code) {
return true;
}
}
return false;
} else {
return true;
}
}
}
以上是完整的转换代码,OMG
重点是:
private final int code;
Data Classes 竟然在转成的时候把Int转化成了int
而不是我们理解的Integer
抱着试试的态度 我修改了一些我们BaseMessage
data class BaseMessage(val message: String, val code: Int?)
我们给code增加了?
改为可为null,看下转换结果:
@NotNull
private final String message;
@Nullable
private final Integer code;
@NotNull
public final String getMessage() {
return this.message;
}
@Nullable
public final Integer getCode() {
return this.code;
}
神奇的事情发生了,当我们让code可为空时,Int转成的Integer
这样我们就理解了
kotlin的确很细心,无处不在防止空指针
总结
1.Data Classes在我们定义类型时,如果包含基础数据类型,在我们定义不为空的时候,防止空指针,做了这样的转换.
- 尽量不要以0一种类型标准,因为在int中默认就是0,因为这种定义可能会不小心引起一场灾难
网友评论