Java 中作为 lambda 表达式的完整构造函数调用的方法引用
Method reference with a full constructor call as a lambda expression in Java
不久前,我遇到了一个 比我的更好的方法,它使用了一个相当新的方法来替代 lambda。
Stream.generate(new AtomicInteger(1)::getAndIncrement)...
我查看了有关 Method references 的 Oracle 规范,其中定义了 4 种类型:
- 引用静态方法
ContainingClass::staticMethodName
- 引用特定对象的实例方法
containingObject::instanceMethodName
- 引用特定类型的任意对象的实例方法
ContainingType::methodName
- 对构造函数的引用
ClassName::new
我很难对这个进行分类。我没有发现任何关于 SO 的问题或文档中解释的任何相关内容。这将如何翻译成匿名 class?
我的怀疑是:
IntStream.generate(new IntSupplier() {
AtomicInteger atom = new AtomicInteger(1);
@Override
public int getAsInt() {
return atom.getAndIncrement();
}
})....
...我不明白这怎么可能。乍一看,我猜表达式是:
IntStream.generate(new IntSupplier() {
@Override
public int getAsInt() {
return new AtomicInteger(1).getAndIncrement();
}
})....
...但这就是() -> new AtomicInteger(1).getAndIncrement()
。
这种表达式是在哪里定义的,在lambda/anonymousclass中如何重写?
你可以替换
Stream.generate(new AtomicInteger(1)::getAndIncrement)...
和
AtomicInteger containingObject = new AtomicInteger(1);
Stream.generate(containingObject::getAndIncrement)...
即此方法引用属于第二类方法引用 - Reference to an instance method of a particular object
.
您应该注意 AtomicInteger
实例创建不是 IntSupplier
实现的一部分。 Java 7 等价物是:
AtomicInteger aint = new AtomicInteger(1);
IntStream.generate(new IntSupplier() {
@Override
public int getAsInt() {
return aint.getAndIncrement();
}
})...
.
就是第二种:对特定对象的方法的引用,幕后没有额外的逻辑。
嗯new AtomicInteger(1)
returns一个实例,所以这是第二个。如何翻译的确切细节是特定于实现的,但它是创建的单个实例,并且由 JLS 15.13.3
支持
First, if the method reference expression begins with an ExpressionName or a Primary, this subexpression is evaluated
用简单的英语来说,::
之前的部分在 第一次遇到它的声明时被评估 。
你的假设几乎是正确的,这就像在函数本身之外生成一个实例并使用它 - 因为它实际上是最终的,所以这是允许的。
不久前,我遇到了一个
Stream.generate(new AtomicInteger(1)::getAndIncrement)...
我查看了有关 Method references 的 Oracle 规范,其中定义了 4 种类型:
- 引用静态方法
ContainingClass::staticMethodName
- 引用特定对象的实例方法
containingObject::instanceMethodName
- 引用特定类型的任意对象的实例方法
ContainingType::methodName
- 对构造函数的引用
ClassName::new
我很难对这个进行分类。我没有发现任何关于 SO 的问题或文档中解释的任何相关内容。这将如何翻译成匿名 class?
我的怀疑是:
IntStream.generate(new IntSupplier() {
AtomicInteger atom = new AtomicInteger(1);
@Override
public int getAsInt() {
return atom.getAndIncrement();
}
})....
...我不明白这怎么可能。乍一看,我猜表达式是:
IntStream.generate(new IntSupplier() {
@Override
public int getAsInt() {
return new AtomicInteger(1).getAndIncrement();
}
})....
...但这就是() -> new AtomicInteger(1).getAndIncrement()
。
这种表达式是在哪里定义的,在lambda/anonymousclass中如何重写?
你可以替换
Stream.generate(new AtomicInteger(1)::getAndIncrement)...
和
AtomicInteger containingObject = new AtomicInteger(1);
Stream.generate(containingObject::getAndIncrement)...
即此方法引用属于第二类方法引用 - Reference to an instance method of a particular object
.
您应该注意 AtomicInteger
实例创建不是 IntSupplier
实现的一部分。 Java 7 等价物是:
AtomicInteger aint = new AtomicInteger(1);
IntStream.generate(new IntSupplier() {
@Override
public int getAsInt() {
return aint.getAndIncrement();
}
})...
.
就是第二种:对特定对象的方法的引用,幕后没有额外的逻辑。
嗯new AtomicInteger(1)
returns一个实例,所以这是第二个。如何翻译的确切细节是特定于实现的,但它是创建的单个实例,并且由 JLS 15.13.3
First, if the method reference expression begins with an ExpressionName or a Primary, this subexpression is evaluated
用简单的英语来说,::
之前的部分在 第一次遇到它的声明时被评估 。
你的假设几乎是正确的,这就像在函数本身之外生成一个实例并使用它 - 因为它实际上是最终的,所以这是允许的。