gpt4 book ai didi

java - 方法引用是否在幕后调用 ArrayNode 类的构造函数?

转载 作者:行者123 更新时间:2023-12-02 09:06:42 26 4
gpt4 key购买 nike

我有一个程序示例,它使用方法引用运算符(双冒号):

public class VersionNumberComparator implements Comparator<String> {
@Override
public int compare(String version1, String version2) {
Integer[] array1 = Arrays.stream(version1.split("\\."))
.map(Integer::parseInt)
.toArray(Integer[]::new);
Integer[] array2 = Arrays.stream(version2.split("\\."))
.map(Integer::parseInt)
.toArray(Integer[]::new);
int length1 = array1.length;
int length2 = array2.length;
int idx = 0;
while (idx < length1 || idx < length2) {
if (idx < length1 && idx < length2) {
if (array1[idx] < array2[idx]) {
return -1;
} else if (array1[idx] > array2[idx]) {
return 1;
}
} else if (idx < length1) {
if (array1[idx] != 0) {
return 1;
}
} else {
if (array2[idx] != 0) {
return -1;
}
}
idx++;
}
return 0;
}
}

在比较应用程序的版本号之前,我需要拆分数字并从左侧到右侧进行比较:

Integer[] array1 = Arrays.stream(version1.split("\\."))
.map(Integer::parseInt)
.toArray(Integer[]::new);
Integer[] array2 = Arrays.stream(version2.split("\\."))
.map(Integer::parseInt)
.toArray(Integer[]::new);

方法引用有四种类型。其中之一是:对构造函数 ClassName::new 的引用。因此,如果我正在调试并进入 .toArray(Integer[]::new);,我会得到:

@Override
@SuppressWarnings("unchecked")
public final <A> A[] toArray(IntFunction<A[]> generator) {
@SuppressWarnings("rawtypes")
IntFunction rawGenerator = (IntFunction) generator;
return (A[]) Nodes.flatten(evaluateToArrayNode(rawGenerator), rawGenerator)
.asArray(rawGenerator);
}

然后:

    /** Node class for a reference array */
private static class ArrayNode<T> implements Node<T> {
final T[] array;
int curSize;

@SuppressWarnings("unchecked")
ArrayNode(long size, IntFunction<T[]> generator) {
if (size >= MAX_ARRAY_SIZE)
throw new IllegalArgumentException(BAD_SIZE);
this.array = generator.apply((int) size);
this.curSize = 0;
}
...

在这种特殊情况下,方法引用在底层调用 ArrayNode 类的构造函数,因为它需要运算符 ::,我是否理解正确?

最佳答案

evaluateArrayNode 方法最终通过一系列中间方法调用间接调用 ArrayNode 构造函数。

从我的调试 View :

// this.array = generator.apply((int) size);
Nodes$FixedNodeBuilder<T>(Nodes$ArrayNode<T>).<init>(long, IntFunction<T[]>) line: 646
Nodes$FixedNodeBuilder<T>.<init>(long, IntFunction<T[]>) line: 1199
Nodes.builder(long, IntFunction<T[]>) line: 167
ReferencePipeline$3(ReferencePipeline<P_IN,P_OUT>).makeNodeBuilder(long, IntFunction<P_OUT[]>) line: 131
ReferencePipeline$3(AbstractPipeline<E_IN,E_OUT,S>).evaluate(Spliterator<P_IN>, boolean, IntFunction<E_OUT[]>) line: 543
ReferencePipeline$3(AbstractPipeline<E_IN,E_OUT,S>).evaluateToArrayNode(IntFunction<E_OUT[]>) line: 260
ReferencePipeline$3(ReferencePipeline<P_IN,P_OUT>).toArray(IntFunction<A[]>) line: 438
// Arrays.stream(new int[] { }).toArray(Integer[]::new);
Test.main(String[]) line: 15

因此,与通过 :: 语法引用的构造函数没有关系。

事实上,在最后一个代码块中,参数generator引用了Integer[]::new。您可以通过自己实现生成器函数来检查这一点,例如:

class Generator implements IntFunction<Integer[]> {
@Override
public Integer[] apply(int value) {
System.out.println(new Exception().getStackTrace()[2]);
return new Integer[value];
}
}

Arrays.stream(new int[] { }).toArray(new Generator());

这将打印:

java.util.stream.Nodes$ArrayNode.<init>(Nodes.java:646)

这到底是哪一行:

this.array = generator.apply((int) size);

关于java - 方法引用是否在幕后调用 ArrayNode 类的构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59759194/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com