这个问题是由我的好奇心驱使的,所以我希望得到一个完整的答案,而不是简单的“是”或“否”。
让我们考虑这段代码:
// Is stored in util files and used to omit annoying (this as? Smth)?.doSmth()
inline fun <reified T> Any?.cast(): T? {
return this as? T
}
class PagingOnScrollListener(var onLoadMore: (currentPage: Int, pageSize: Int) -> Unit) : RecyclerView.OnScrollListener() {
constructor() : this({ _, _ -> Unit })
private var loading = false
private var currentPage = 0
private var latestPageSize = -1
var visibleThreshold = VISIBLE_THRESHOLD_DEFAULT
var pageSize = PAGE_SIZE_DEFAULT
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val linearLayoutManager = recyclerView.linearLayoutManager
val totalItemCount = linearLayoutManager.itemCount
val lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition()
if (!loading && totalItemCount - lastVisibleItem <= visibleThreshold
&& latestPageSize !in 0 until pageSize) {
currentPage++
loading = true
onLoadMore(currentPage, pageSize)
}
}
private inline val RecyclerView.linearLayoutManager
get() = layoutManager?.cast<LinearLayoutManager>()
?: throw IllegalStateException("PagingOnScrollListener requires LinearLayoutManager to be attached to RecyclerView!")
companion object {
private const val VISIBLE_THRESHOLD_DEFAULT = 4
private const val PAGE_SIZE_DEFAULT = 10
}
}
当我在 AndroidStudio 中使用“显示 Kotlin 字节码”工具,然后单击“反编译”按钮时,我看到了这个 java 代码(我删除了一些不相关的东西):
public final class PagingOnScrollListener extends RecyclerView.OnScrollListener {
private boolean loading;
private int currentPage;
private int latestPageSize;
private int visibleThreshold;
private int pageSize;
@NotNull
private Function2 onLoadMore;
private static final int VISIBLE_THRESHOLD_DEFAULT = 4;
private static final int PAGE_SIZE_DEFAULT = 10;
public PagingOnScrollListener(@NotNull Function2 onLoadMore) {
Intrinsics.checkParameterIsNotNull(onLoadMore, "onLoadMore");
super();
this.onLoadMore = onLoadMore;
this.latestPageSize = -1;
this.visibleThreshold = 4;
this.pageSize = 10;
}
public PagingOnScrollListener() {
this((Function2)null.INSTANCE);
}
public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy) {
Intrinsics.checkParameterIsNotNull(recyclerView, "recyclerView");
super.onScrolled(recyclerView, dx, dy);
int $i$f$getLinearLayoutManager = false;
RecyclerView.LayoutManager var10000 = recyclerView.getLayoutManager();
if (var10000 != null) {
Object $this$cast$iv$iv = var10000;
int $i$f$cast = false;
var10000 = $this$cast$iv$iv;
if (!($this$cast$iv$iv instanceof LinearLayoutManager)) {
var10000 = null;
}
LinearLayoutManager var10 = (LinearLayoutManager)var10000;
if (var10 != null) {
LinearLayoutManager linearLayoutManager = var10;
int totalItemCount = linearLayoutManager.getItemCount();
int lastVisibleItem = linearLayoutManager.findLastVisibleItemPosition();
if (!this.loading && totalItemCount - lastVisibleItem <= this.visibleThreshold) {
int var11 = this.pageSize;
int var12 = this.latestPageSize;
if (0 <= var12) {
if (var11 > var12) {
return;
}
}
int var10001 = this.currentPage++;
this.loading = true;
this.onLoadMore.invoke(this.currentPage, this.pageSize);
}
return;
}
}
throw (Throwable)(new IllegalStateException("EndlessOnScrollListener requires LinearLayoutManager to be attached to RecyclerView!"));
}
}
在这里我们可以看到一些奇怪的代码:
1.
// in constructor:
Intrinsics.checkParameterIsNotNull(onLoadMore, "onLoadMore");
super();
Java 要求super
call 是构造函数主体中的第一条语句。
2.
this((Function2)null.INSTANCE);
这对应于constructor() : this({ _, _ -> Unit })
什么null.INSTANCE
意思?为什么没有预期的匿名对象?
this(new Function2() {
@Override
public Object invoke(Object o1, Object o2) {
return kotlin.Unit.INSTANCE;
}
});
3.
方法上没有@Override
注释onScrolled
。override
用修饰符为方法添加注释是否太难了?但是存在@NonNull
和@Nullable
注释。
4.
int $i$f$getLinearLayoutManager = false;
Boolean
值被分配给int
变量?为什么这条线出现在这里?这个变量没有用处。为什么它声明一个不会被使用的变量?
5.
RecyclerView.LayoutManager var10000 = recyclerView.getLayoutManager();
if (var10000 != null) {
Object $this$cast$iv$iv = var10000; // what's the purpose of this assignment?
int $i$f$cast = false;
var10000 = $this$cast$iv$iv; // Incompatible types. RecyclerView.LayoutManager was expected but got Object.
...
6.
if (!this.loading && totalItemCount - lastVisibleItem <= this.visibleThreshold) {
int var11 = this.pageSize;
int var12 = this.latestPageSize;
if (0 <= var12) {
if (var11 > var12) {
return;
}
}
...
}
为什么不让它变得更简单呢?
if (!this.loading && totalItemCount - lastVisibleItem <= this.visibleThreshold && (0 > this.latestPageSize || this.pageSize < this.latestPageSize))
7.
// Unhandled exception: java.lang.Throwable.
throw (Throwable)(new IllegalStateException("EndlessOnScrollListener requires LinearLayoutManager to be attached to RecyclerView!"));
如果我们知道,为什么它会IllegalStateException
转换?目的是什么?Throwable
IllegalStateException extends Throwable
这真的是在生产中执行的代码还是 Java Decompiler 无法弄清楚所有这些东西?