首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >什么是Java中的“SAM类型”?

什么是Java中的“SAM类型”?
EN

Stack Overflow用户
提问于 2018-03-15 04:41:07
回答 1查看 0关注 0票数 0

阅读Java-8规范,我不断看到对'SAM类型'的引用。我一直无法找到明确的解释。

什么是SAM类型,什么时候可以使用某个示例场景?

EN

回答 1

Stack Overflow用户

发布于 2018-03-15 14:36:37

总结乔恩发布的链接的情况下,它曾经出现故障,“SAM”代表“单一抽象方法”和“SAM型”是指接口等RunnableCallable等Lambda表达式,在Java 8中的新功能,被认为是一个SAM类型,并可以自由地转换为它们。

例如,使用这样的界面:

代码语言:javascript
复制
public interface Callable<T> {
    public T call();
}

你可以Callable像这样声明一个使用lambda表达式:

代码语言:javascript
复制
Callable<String> strCallable = () -> "Hello world!";
System.out.println(strCallable.call()); // prints "Hello world!"

这种情况下的Lambda表达式大多只是语法糖。它们在代码方面比匿名类更好,而且对方法命名的限制更少。从链接中获取此示例:

代码语言:javascript
复制
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使用invokedynamic在Java 7中添加的字节码指令来实现这些。我之前说过,声明Lambda会创建一个匿名类的实例CallableComparable类似的实例,但这并非严格对待。相反,第一次invokedynamic调用它时,它会使用该LambdaMetafactory.metafactory方法创建一个Lambda函数处理程序,然后在将来调用Lambda时使用此缓存实例。

这种方法非常复杂,甚至包括可以直接从堆栈内存中读取原始值和引用以传递到Lambda代码的代码(例如,需要分配一个Object[]数组来调用Lambda),但它允许将来的迭代实现Lambda实现替换旧的实现而不必担心字节码兼容性。如果Oracle的工程师在较新版本的JVM中更改基础Lambda实现,则在旧JVM上编译的Lambdas将使用较新的实现。

作为旁注,链接上的语法已过时。查看Lambda表达式Java Trail以查看当前的语法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004258

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档