- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
Java 可以正确推断 SAM 类型并允许我传递 lambda 作为它们实现的替代,但是当我尝试将一种 SAM 类型转换为具有相同签名的另一种时,相同的机制失败了:
public static Supplier<String> saySomething(){
return () -> "Hello";
}
@FunctionalInterface
interface Greeter {
String greet();
}
public static Greeter getGreeting1(){
// this compiles and runs just fine
return () -> saySomething().get();
}
public static Greeter getGreeting2(){
// this fails at compile:
// java: incompatible types: java.util.function.Supplier<java.lang.String> cannot be converted to Greeter
return saySomething();
}
public static Greeter getGreeting3(){
// this compiles without warnings(probably only because a Supplier<String> might
// also implement the Greeter interface, by chance) but if you call it will fail
// at runtime with a java.lang.ClassCastException
return (Greeter) saySomething();
}
我试图理解为什么 JVM 不会让 lambda 被当作这里的一件事和那里的另一件事,因为它只需要为此进行另一个 SAM 转换。我怀疑这是因为 lambda 被提升为隐藏的匿名类,但有人可以给出明确的答案吗?
此外,是否有任何解决方法(除了将每个 SAM 转换包装在另一个 lambda 中,如第一个示例中所示)以允许它工作?
最佳答案
Lambda 表达式是一种 Java 语言工件,而不是 JVM 功能。
其中涉及多个编译时功能,这些功能在运行时不存在,而且在运行时执行起来成本太高。
编译器使用类型推断,结合通用类型系统,来确定要实现的接口(interface)。
然后检查接口(interface)的潜在复杂类型层次结构,包括哪个方法重写哪个,再次考虑泛型类型系统的规则,最终确定哪些抽象方法(不包括 private
、default
和 static
方法)不匹配 java.lang.Object
的 public
方法是留待实现。
如果只有一个方法可以实现,erasure方法和所有Bridge Methods被识别,以包含在构建第一步中推断的功能接口(interface)实例的配方中。
整体操作是一个object creation ,尽管实现可能会重用现有对象:
At run time, evaluation of a lambda expression is similar to evaluation of a class instance creation expression, insofar as normal completion produces a reference to an object.
相比之下,类型转换是 type checking表达式:
A cast expression […] checks, at run time, that a reference value refers to an object either whose class is compatible with a specified reference type or list of reference types […]
如果成功,结果仍然是引用同一个对象。所以如果你有
interface A {
int test();
}
interface B extends A {
default int test() {
return method2() + 1;
}
int method2();
}
B b1 = () -> 10;
A a1 = (A)b1;
System.out.println(a1.test());
它将打印 11
,因为变量 a1
仍然包含对与 b1
相同的 B
实例的引用> 及其 test()
方法实现为 method2() + 1
。
相比之下,
A a2 = () -> 10;
System.out.println(a2.test());
将打印 10
,因此,很明显这不能是与上面的 b1
相同的对象,无论对象的创建方式如何(即相同lambda 表达式 () -> 10
).
将此 A
实例转换为 B
,如 B b2 = (B)a2;
假设其 method2()
由于兼容的功能签名不可能像 test()
一样实现,因为它会导致关于结果的 test()
方法的矛盾行为(如果仍然不相信,想想如果我们再次将 b2
转换回 A
会发生什么。
相反,当你使用像这样的方法引用时
B b2 = a2::test;
您明确表示 b2
将是与 a2
和 b2
的功能方法(method2())不同的对象
) 将表现出与 a2
的功能方法 (test()
) 相同的行为。因此,b2
的 test()
方法与 a2
的 test()
方法具有不同的行为是一致的> 方法。
关于Java - 为什么具有匹配签名的 SAM 类型不可互换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73981904/
我正在构建一些无服务器应用程序并尝试使用 SAM。我已经阅读了一些教程和一些使用 sam build ,而其他人使用 sam package . 这些命令之间有什么区别?似乎 sam 包更难使用。 最
我有一个 AWS SAM 模板,它定义了一个引用其他几个嵌套应用程序的应用程序。 我需要将一个嵌套应用程序的输出传递给另一个嵌套应用程序的参数,但我不确定语法是否正确。 这是包含嵌套应用程序的模板示例
我使用 JSONschema 定义了一个模型并将其设置为 lambda。我可以看到模型被添加到请求正文中,如下图所示 但我还需要设置请求验证器来验证它。这是我下面的示例 AWS SAM 模板。 Res
我正在尝试创建具有多个 AWS 无服务器功能的 AWS SAM 应用程序。 该应用程序有 1 个 template.yaml 文件,其中包含 2 个不同的无服务器 lambda 函数的资源,例如“Co
我一直在寻找 aws-sam-local 单元测试策略,但没有找到太多。只是在寻找建议? 最佳答案 要在“tests”目录中运行“test_handler.py”,您可以执行以下操作。您可能不需要所有
我正在尝试按照 Hello World example 部署 AWS 无服务器应用程序,但在使用 sam deploy --guided 时出现安全约束不满足错误。我在每个提示下按 Enter 以接受
我正在开发一个用 python3.6 编写的 Lambda 函数以进行本地测试,然后在工作后部署到 AWS。为此,我正在使用 PyCharm 的 AWS Serverless Toolkit。 不包含
我正在向现有无服务器应用程序添加 SAM 模板。我有一个没有。调用其他 lambda 的 lambda,并且调用者具有指定“被调用者”或调用的 lambda 的 ARN 的策略。在这种情况下,策略创建
使用 sam build我希望不包含 aws-sdk 的命令包,因为 Node.js Lambda 运行时已经包含它。 据我了解sam build对于 nodejs 是 claudia pack 的端
我正在开发具有 lambda 函数的 SAM 应用程序,API 网关作为事件源。 API Endpoint 是一种 POST 方法,需要在请求正文中设置一组参数。 API Gateway 通过使用 A
嗨,我有一个 sam 应用程序,它有一个 lambda 函数,可以从按预期工作的其余端点调用,但是当我尝试使用 sam local start-lambda 或 sam local start-api
我正在尝试使用 SAM(无服务器应用程序模型)和用 Java 编写的 Lambda 构建一个 AWS 应用程序。 通过在模板中使用这样的资源定义,我能够让它在本地运行: Resources: He
我使用 AWS SAM 生成我的 Lambda/API。但我希望能够获取此 RestApi,以便我可以在另一个 SAM 模板中使用它。 这个想法是拥有 1 个基础设施 CloudFormation/S
我可以调用本地 lambda http 端点(sam local start-lambda),但是如何使用(模拟)AWS 事件(s3 等)触发该 lambda 端点,就像使用 Dockerized l
我尝试直接将编译后的 CloudFormation 文件与 SAM Local 结合使用。我找不到办法做到这一点,有人成功实现了这一点吗? 最佳答案 好吧,假设您想在本地测试您配置的 lambda,您
我目前正在尝试设置一个应该执行简单 TestCafe 测试的 AWS Lambda (nodejs10.x) 函数。 如果我使用 sam local invoke --no-event 在本地运行我的
我使用AWS SAM应用程序和SAM模板来模拟API服务(API Gateway和Lambda)。Lambda运行在Python3.8上。。最近,我升级到了最新版本的SAM CLI。我使用命令‘Sam
按照 https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli
我有一个需要通过 Amazon API Gateway 触发的 lambda 函数。有没有办法将现有的 API(使用 AWS 控制台创建)包含到 AWS SAM 模板中? 最佳答案 SAM 尚不支持模
在尝试 SAM 部署时,我收到以下拒绝信息: 1 validation error detected: Value 'arn:aws:iam::${AWS::AccountId}:role/Lambd
我是一名优秀的程序员,十分优秀!