Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么是';SAM类型';在爪哇?_Java_Lambda_Java 8_Terminology - Fatal编程技术网

Java 什么是';SAM类型';在爪哇?

Java 什么是';SAM类型';在爪哇?,java,lambda,java-8,terminology,Java,Lambda,Java 8,Terminology,在阅读Java-8规范时,我不断看到对“SAM类型”的引用。我还没能找到一个关于这是什么的清晰解释 什么是SAM类型?什么时候可以使用SAM类型?总结一下,如果出现问题,“SAM”代表“单一抽象方法”,而“SAM类型”指的是像Runnable,Callable等接口。Lambda表达式是Java 8中的一个新特性,被视为SAM类型,可以自由转换为SAM类型 例如,对于这样的接口: public interface Callable<T> { public T call();

在阅读Java-8规范时,我不断看到对“SAM类型”的引用。我还没能找到一个关于这是什么的清晰解释

什么是SAM类型?什么时候可以使用SAM类型?总结一下,如果出现问题,“SAM”代表“单一抽象方法”,而“SAM类型”指的是像
Runnable
Callable
等接口。Lambda表达式是Java 8中的一个新特性,被视为SAM类型,可以自由转换为SAM类型

例如,对于这样的接口:

public interface Callable<T> {
    public T call();
}
Callable<String> strCallable = () -> "Hello world!";
System.out.println(strCallable.call()); // prints "Hello world!"
在此上下文中,Lambda表达式大多只是语法上的糖分。它们在代码中比匿名类看起来更好,并且对方法命名的限制更少。以链接中的示例为例:

class Person { 
    private final String name;
    private final int age;

    public static int compareByAge(Person a, Person b) { ... }

    public static int compareByName(Person a, Person b) { ... }
}

Person[] people = ...
Arrays.sort(people, Person::compareByAge);
这将使用与
Comparator不共享相同名称的特定方法创建
Comparator
。compare
,这样您就不必遵循方法的接口命名,并且可以在一个类中有多个比较重写,然后通过lambda表达式动态创建比较器

深入…

在更深层次上,Java使用Java 7中添加的
invokedynamic
字节码指令来实现这些。我在前面说过,声明Lambda会创建一个类似于匿名类的
Callable
Comparable
的实例,但严格来说这不是真的。相反,第一次调用
invokedynamic
时,它使用创建一个Lambda函数处理程序,然后在以后的Lambda调用中使用该缓存实例。更多信息可在中找到

这种方法很复杂,甚至包括可以直接从堆栈内存读取原语值和引用以传递到Lambda代码的代码(例如,为了避免需要分配
对象[]
数组来调用Lambda),但它允许Lambda实现的未来迭代替换旧的实现,而不必担心字节码兼容性。如果Oracle的工程师在较新版本的JVM中更改基础Lambda实现,则在较旧JVM上编译的Lambda将自动使用较新的实现,而不需要开发人员进行任何更改



1链接上的语法已过时。请查看以查看当前语法。

请参阅(我在一次搜索后找到了该语法,这将我带到了另一个SO问题)。请不要让人们参考过时的信息。稍长一点的搜索会让你找到更新的版本:,它本身已经有18个月了,现在在许多地方已经过时了。OP的问题在FAQ的一页上得到了回答,我一直在努力跟上直到最近快速变化的语言和API开发的最新情况。@MauriceNaftalin您也可以直接链接,这是由开发团队保持最新的。当前术语是“功能接口”。@MauriceNaftalin:抱歉,错过了那个。如果我发现的话,肯定会和它有联系。