Rom*_*nov 16 java java-8 method-reference
在Java 8中有"方法参考"功能.其中一种是"引用特定类型的任意对象的实例方法"
http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html#type
有人可以解释"特定类型的任意对象"在这种情况下的含义吗?
小智 19
Oracle Doc链接的示例是:
String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
Run Code Online (Sandbox Code Playgroud)
lambda相当于
String::compareToIgnoreCase
Run Code Online (Sandbox Code Playgroud)
将会
(String a, String b) -> a.compareToIgnoreCase(b)
Run Code Online (Sandbox Code Playgroud)
该Arrays.sort()方法正在寻找比较器作为其第二个参数(在此示例中).传递String::compareToIgnoreCase创建一个比较器a.compareToIgnoreCase(b)作为比较方法的主体.然后你问好了什么a和b.比较方法的第一个参数变为a第二个参数b.这些是String类型(特定类型)的任意对象.
不明白?
阅读更多信息来源:http: //moandjiezana.com/blog/2014/understanding-method-references/
小智 13
它是某种类型的实例方法的引用.在示例的情况下,compareToIgnoreCase是一种方法String.程序知道它可以在一个实例上调用此方法String,因此它可以获取该类型的引用和任何对象,并保证该方法存在.
我会将它与Method类进行比较,因为它们引用了一个方法,并且可以在某种类型的任意实例上调用.
例如,它可以使用两个String对象并调用compareToIgnoreCase一个对象,并使用另一个作为参数来匹配方法签名.这允许它根据数组类型的任何方法获取数组并对其进行排序,而不是要求比较器实例执行此操作.
以下是未点击问题链接的任何人的示例:
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda", "George" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
Run Code Online (Sandbox Code Playgroud)
小智 6
请参阅下面的代码示例,它解释了https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html中描述的“对特定类型的任意对象的实例方法的引用”类别
import java.util.Arrays;
class Person{
String name;
//constructor
public Person(String name){
this.name = name;
}
//instance method 1
public int personInstanceMethod1(Person person){
return this.name.compareTo(person.name);
}
//instance method 2
public int personInstanceMethod2(Person person1, Person person2){
return person1.name.compareTo(person2.name);
}
}
class Test {
public static void main (String[] args) throws Exception{
Person[] personArray = {new Person("A"), new Person("B")};
// Scenario 1 : Getting compiled successfully
Arrays.sort(personArray, Person::personInstanceMethod1);
// Scenario 2 : Compile failure
Arrays.sort(personArray, Person::personInstanceMethod2);
// Scenario 3 : Getting compiled successfully.
Person personInstance = new Person("C");
Arrays.sort(personArray, personInstance::personInstanceMethod2);
// Scenario 4 : Getting compiled successfully. As the same way as "Scenario 1"
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
}
}
Run Code Online (Sandbox Code Playgroud)
场景 1 和场景 4 描述了https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html中描述的“对特定类型的任意对象的实例方法的引用”类别
如果方法参数采用与元素的实例 Type 相同的实例 Type 中的变量,则可以使用 Type.( Person::personInstanceMethod1)调用该实例方法
将“ ”类personInstanceMethod1中的“”实例方法Person与compareToIgnoreCase“”类中的“”实例方法进行比较String(https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#compareToIgnoreCase-java.lang .String- ) 以查看相似性。两者都采用具有相同类型的单个参数。
比较场景 1 和场景 2,看看有什么不同。
小智 6
我认为在这种情况下,由于在文档中使用未定义的术语,理解这个概念变得更加困难。
请记住,方法引用作为 lambda 的一种类型,实现了函数式接口,并且只要可以在程序中引用它,就可以使用与接口签名匹配的任何方法。
四种方法引用中,分别代表访问(引用)该方法所需的不同方式。这三个方法的语法非常简单:如果它是静态方法,则在 :: 运算符之前使用类名;如果它是对象中的实例方法,则通常使用该对象的引用变量,或者如果它是构造函数使用 ClassName::new。
第四种是您要调用的方法,该方法是传递给函数的参数的实例方法。使用 lambda 就没有问题,因为您可以引用参数变量,如下所示:
(String someString) -> someString.toLowerCase();
Run Code Online (Sandbox Code Playgroud)
但是,由于方法引用中没有显式参数变量,因此使用的语法是:
String::toLowerCase;
Run Code Online (Sandbox Code Playgroud)
编译器采用“特定类型”(String)来引用“任意对象”(参数中传递的对象)中包含的函数方法(toLowerCase)。使用术语“任意对象”是因为每次执行方法引用时,参数中传递的实际对象可能不同。