0

我有一个非常基本forEach的代码,如下面的代码。

val array = arrayOf(1, 2)
val list = listOf(1, 2)

array.forEach(::println)
list.forEach(::println)

但是,如果用Java反编译,则forEach根据Array和List的不同,实现方法不同。

Integer[] array = new Integer[]{ 1, 2 };
List list = CollectionsKt.listOf(new Integer[]{ 1, 2 });
Integer[] var4 = array;
int var5 = array.length;

int p1;
for(p1 = 0; p1 < var5; ++p1) {
    Object element $iv = var4[p1];
    int p1 =((Number) element $iv).intValue();
    System.out.println(p1);
}

Iterable $this$forEach$iv = (Iterable)list;
Iterator var11 = $this$forEach$iv.iterator();

while(var11.hasNext()) {
    Object element $iv = var11.next();
    p1 = ((Number) element $iv).intValue();
    System.out.println(p1);
}

通过检查 的实现方法forEach,两者都是以相同的for (element in this) action(element)方法实现的。

public inline fun <T> Array<out T>.forEach(action: (T) -> Unit): Unit {
    for (element in this) action(element)
}

public inline fun <T> Iterable<T>.forEach(action: (T) -> Unit): Unit {
    for (element in this) action(element)
}

我一直在寻找 Array 和 List 之间的区别,以找出为什么 Array 和 List 的实现方式不同in,但我没有找到与in关键字相关的任何内容。为什么 Array 和 List 的 in 实现看起来不同?

4

1 回答 1

1

您希望代码翻译成如下内容:

for (Integer element: array) {
    System.out.println(element);
}

for (Integer element: list) {
    System.out.println(element);
}

正确的?但是,请注意,Java 中的这些 for 循环是语法糖。这些循环与(这是 Java 编译器将这些循环翻译成的内容)完全相同:

Integer[] a = array;
for (int i = 0; i < a.length; i++) {
    Integer element = a[i];
    System.out.println(element);
}

for (Iterator<Integer> iter = list.iterator(); iterator.hasNext(); ) {
    Integer element = (Integer) iterator.next();
    System.out.println(element);
}

注意到即使在 Java 中,数组和可迭代对象的翻译方式也不同。这在Java 语言规范第 14.14.2 节中指定。这样做的原因是因为数组iterator在 Java 中没有方法(所以不能使用第二种形式),并且Iterables 不能被索引[](所以不能使用第一种形式)。

您看到的其他差异主要是由于类型擦除,这就是为什么您会看到到处都插入了强制转换,以及您使用的反编译器的实现细节。请注意,列表的第二个 for 循环也可以写成您看到的 while 循环

Iterator<Integer> iter = list.iterator();
while (iterator.hasNext()) {
    Integer element = (Integer) iterator.next();
    System.out.println(element);
}

由于您的反编译器只有要查看的字节码,因此这个循环实际上是 for 循环还是 while 循环的问题是没有实际意义的。

于 2021-11-14T09:06:18.230 回答