Nit*_*ava 5 java method-reference
在 Java 中的实例方法的情况下,我无法掌握方法引用的概念
例如,在下面的示例中,编译器在列表行中给出错误。
我看过 String::toUpperCase 的例子。
我对 (1) String 是一个类而 toUpperCase 是实例方法这一点感到困惑。Java 允许 String::toUpperCase (2) 为什么在我的情况下不允许:- AppTest::makeUppercase
package mja;
import java.util.function.Function;
public class AppTest {
public String makeUppercase(String source){
return source.toUpperCase();
}
public void printFormattedString(String string, Function<String, String> formatter){
System.out.println(formatter.apply(string));
}
public static void main(String[] args) {
AppTest appTest = new AppTest();
String source = "Hello World!";
// Below statement compiled successfully
appTest.printFormattedString(source, appTest::makeUppercase);
// Getting error that non-static method can't be referenced from static context
appTest.printFormattedString(source, AppTest::makeUppercase);
}
}
Run Code Online (Sandbox Code Playgroud)
为什么不允许AppTest::makeUppercase?
简而言之,“对特定类型的任意对象的实例方法的引用”AppTest::makeUppercase无效。
必须实现接口AppTest::makeUppercaseFunction<AppTest, String>才能成为有效引用。
细节:
Java中有4种方法引用:
ContainingClass::staticMethodName- 静态方法的引用containingObject::instanceMethodName- 对特定对象的实例方法的引用ContainingType::methodName- 对特定类型的任意对象的实例方法的引用ClassName::new- 对构造函数的引用每一种方法引用都需要相应的Function接口实现。您可以使用对特定类型的任意对象的实例方法的引用作为参数。这种方法引用在方法引用中没有显式参数变量,并且需要接口的实现Function<ContainingType, String>。换句话说,左操作数的类型必须是AppTest可AppTest::makeUppercase编译的。String::toUpperCase工作正常,因为参数类型和实例类型相同 - String。
import static java.lang.System.out;
import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
class ReferenceSource {
private String value;
public ReferenceSource() {
}
public ReferenceSource(String value) {
this.value = value;
}
public String doInstanceMethodOfParticularObject(final String value) {
return ReferenceSource.toUpperCase(value);
}
public static String doStaticMethod(final String value) {
return ReferenceSource.toUpperCase(value);
}
public String doInstanceMethodOfArbitraryObjectOfParticularType() {
return ReferenceSource.toUpperCase(this.value);
}
private static String toUpperCase(final String value) {
return Optional.ofNullable(value).map(String::toUpperCase).orElse("");
}
}
public class Main {
public static void main(String... args) {
// #1 Ref. to a constructor
final Supplier<ReferenceSource> refConstructor = ReferenceSource::new;
final Function<String, ReferenceSource> refParameterizedConstructor = value -> new ReferenceSource(value);
final ReferenceSource methodReferenceInstance = refConstructor.get();
// #2 Ref. to an instance method of a particular object
final UnaryOperator<String> refInstanceMethodOfParticularObject = methodReferenceInstance::doInstanceMethodOfParticularObject;
// #3 Ref. to a static method
final UnaryOperator<String> refStaticMethod = ReferenceSource::doStaticMethod;
// #4 Ref. to an instance method of an arbitrary object of a particular type
final Function<ReferenceSource, String> refInstanceMethodOfArbitraryObjectOfParticularType = ReferenceSource::doInstanceMethodOfArbitraryObjectOfParticularType;
Arrays.stream(new String[] { "a", "b", "c" }).map(refInstanceMethodOfParticularObject).forEach(out::print);
Arrays.stream(new String[] { "d", "e", "f" }).map(refStaticMethod).forEach(out::print);
Arrays.stream(new String[] { "g", "h", "i" }).map(refParameterizedConstructor).map(refInstanceMethodOfArbitraryObjectOfParticularType)
.forEach(out::print);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
193 次 |
| 最近记录: |