由于這幾天在看Paging源碼,雖然Kotlin很早就有了,但是一直沒用用上,也沒有仔細(xì)的學(xué)習(xí),這次就借著看源碼的機(jī)會做一次學(xué)習(xí)及整理
Sealed密封類
首先我第一次看到它,我覺得它很像枚舉類,但是它要比枚舉類強(qiáng)大的多。因為子類只要繼承他,就可以自定義擴(kuò)展:
比如
sealed class Test constructor(val num1: Int, val num2: Int){
class Test1 constructor( num1: Int, num2: Int, val num3: Int)
:Test(num1 = num1, num2 = num2)
class Test2 constructor( num1: Int)
:Test(num1 = num1, num2 = 0)
}
fun test(test: Test) : Int = when (test) {
is Test.Test1 -> test.num1 + test.num2 + test.num3
is Test.Test2 -> test.num1 + test.num2
}
這樣看上去是不是很酷炫,密封類的子類可以隨意擴(kuò)展,并且使用時,等于有固定類型的枚舉可供我們使用,然后接下來我們看看這段代碼編譯成java是什么樣子
public abstract static class Test {
private final int num1;
private final int num2;
public final int getNum1() {
return this.num1;
}
public final int getNum2() {
return this.num2;
}
private Test(int num1, int num2) {
this.num1 = num1;
this.num2 = num2;
}
// $FF: synthetic method
public Test(int num1, int num2, DefaultConstructorMarker $constructor_marker) {
this(num1, num2);
}
public static final class Test1 extends test.Test {
private final int num3;
public final int getNum3() {
return this.num3;
}
public Test1(int num1, int num2, int num3) {
super(num1, num2, (DefaultConstructorMarker)null);
this.num3 = num3;
}
}
public static final class Test2 extends test.Test {
public Test2(int num1) {
super(num1, 0, (DefaultConstructorMarker)null);
}
}
可以看到,kotlin轉(zhuǎn)成字節(jié)碼后,再編譯成java代碼,ok
原來是一個靜態(tài)抽象類里帶了兩個靜態(tài)類 =。= 原來如此
然后就是test方法,when is的枚舉不用寫else是如何辦到的呢
public final int test(@NotNull test.Test test) {
Intrinsics.checkNotNullParameter(test, "test");
int var10000;
if (test instanceof test.Test.Test1) {
var10000 = test.getNum1() + test.getNum2() + ((test.Test.Test1)test).getNum3();
} else {
if (!(test instanceof test.Test.Test2)) {
throw new NoWhenBranchMatchedException();
}
var10000 = test.getNum1() + test.getNum2();
}
return var10000;
}
好吧 這里看上去是 如果它既不是Test1, 也不是Test2,那就拋出異常 =。= 原來如此 看來這個密封類也不是特別神奇(2021/1/8)持續(xù)更新