由于这几天在看Paging源码,虽然Kotlin很早就有了,但是一直没用用上,也没有仔细的学习,这次就借着看源码的机会做一次学习及整理
Sealed密封类
首先我第一次看到它,我觉得它很像枚举类,但是它要比枚举类强大的多。因为子类只要继承他,就可以自定义扩展:
比如
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
}
这样看上去是不是很酷炫,密封类的子类可以随意扩展,并且使用时,等于有固定类型的枚举可供我们使用,然后接下来我们看看这段代码编译成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转成字节码后,再编译成java代码,ok
原来是一个静态抽象类里带了两个静态类 =。= 原来如此
然后就是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)持续更新