鉴于:
import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.function.Function;
class Testcase
{
@FunctionalInterface
public interface MyBuilder1<R>
{
R apply(String message);
}
@FunctionalInterface
public interface MyBuilder2<R>
{
R apply(Object message);
}
public static void main(String[] args) throws Throwable
{
Class<?> clazz = IllegalArgumentException.class;
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findConstructor(clazz, MethodType.methodType(void.class, String.class));
MethodHandle myFunctionConstructor = LambdaMetafactory.metafactory(
lookup,
"apply",
MethodType.methodType(Function.class),
mh.type().erase(),
mh,
mh.type()
).getTarget();
MethodHandle myBuilderConstructor1 = LambdaMetafactory.metafactory(
lookup,
"apply",
MethodType.methodType(MyBuilder1.class),
mh.type().erase(),
mh,
mh.type()
).getTarget();
MethodHandle myBuilderConstructor2 = LambdaMetafactory.metafactory(
lookup,
"apply",
MethodType.methodType(MyBuilder2.class),
mh.type().erase(),
mh,
mh.type()
).getTarget();
@SuppressWarnings("unchecked")
Function<String, IllegalArgumentException> functionFactory =
(Function<String, IllegalArgumentException>) myFunctionConstructor.invokeExact();
@SuppressWarnings("unchecked")
MyBuilder1<IllegalArgumentException> myBuilder1Factory =
(MyBuilder1<IllegalArgumentException>) myBuilderConstructor1.invokeExact();
@SuppressWarnings("unchecked")
MyBuilder2<IllegalArgumentException> myBuilder2Factory =
(MyBuilder2<IllegalArgumentException>) myBuilderConstructor2.invokeExact();
IllegalArgumentException runFunction = functionFactory.apply("test");
// IllegalArgumentException runBuilder1 = myBuilder1Factory.apply("test");
IllegalArgumentException runBuilder2 = myBuilder2Factory.apply("test");
}
}
为什么run函数
和runBuilder2
工作,而runBuilder1
抛出以下异常?
java.lang.AbstractMethodError:接收器类test case $ $ Lambda $ 233/0x 0000000800d 21d 88未定义或继承接口MyBuilder1的已解析方法“abstract Java . lang . object apply(Java . lang . string)”的实现。
假设IllegalArgumentExc的
构造函数接受一个String
参数,而不是一个Object
,JVM不应该接受runBuilder1
并抱怨其他两个的参数类型吗?
您的MyBuilder1
R apply(String message);
其擦除类型为
Object apply(String message);
换句话说,与
函数
或MyBuilder2,而不是
的
MethodType
擦除()
方法只是将所有引用类型替换为
>,这对于
代码(除非您想通过Reflection查找接口方法)。</p">
例如,我们可以将返回类型更改为
Object
并保留参数类型:
class Testcase
{
@FunctionalInterface
public interface MyBuilder1<R>
{
R apply(String message);
}
public static void main(String[] args) throws Throwable
{
Class<?> clazz = IllegalArgumentException.class;
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findConstructor(clazz,
MethodType.methodType(void.class, String.class));
MethodHandle myBuilderConstructor1 = LambdaMetafactory.metafactory(
lookup,
"apply",
MethodType.methodType(MyBuilder1.class),
mh.type().changeReturnType(Object.class), // instead of erase()
mh,
mh.type()
).getTarget();
@SuppressWarnings("unchecked")
MyBuilder1<IllegalArgumentException> myBuilder1Factory =
(MyBuilder1<IllegalArgumentException>) myBuilderConstructor1.invokeExact();
IllegalArgumentException runBuilder1 = myBuilder1Factory.apply("test");
runBuilder1.printStackTrace();
}
关于您的最后一个问题,擦除的类型是要实现的类型,而
metafactory
的最后一个参数决定了预期的类型,即从泛型接口类型派生。必要时,生成的代码可能会将类型从擦除的类型转换为此类型。由于此类型在所有情况下都与构造函数签名匹配,因此所有变体都可以调用构造函数。
我对Jest是新手,目前只是在玩一些现有功能的测试。我有一个函数,它获取一个数据数组(来自JSON文件),并将其映射到特定的位置,绘制点。 这是功能点: plotPoint将JSON数据作为参数。该函数之所以有效,是因为它在控制台中正确记录数据,而其他功能按预期工作。 但测试总是失败: 绘图点。测验js 返回此错误: 我认为可能函数是在jsonfile之前的测试中运行的。json已加载,因此我尝试
使用scandir()函数时,我收到以下php警告: Scandir无法打开目录:公共html/page2中不允许操作。php在线3 第2页。php 我想使用这个功能来打印我的根文件夹的文件和子目录,但它不工作。 有人知道怎么修吗?
JSP规范中引入的EL大大简化了JSP页面的开发,使不熟悉Java语言的网页设计人员也可以通过EL表达式在JSP页面中访问很多系统级的资源,以及进行一系列的服务端操作。但EL本身的功能非常有限,为此,EL允许开发人员定义自己的函数来扩展EL的功能。 EL自定义函数实际上就是普通Java类中的方法。但作为EL自定义函数的Java类和方法必须满足如下的条件: l Java类必须被声明成public。
主要内容:操作整个数据表,操作行或列,操作单一元素如果想要应用自定义的函数,或者把其他库中的函数应用到 Pandas 对象中,有以下三种方法: 1) 操作整个 DataFrame 的函数:pipe() 2) 操作行或者列的函数:apply() 3) 操作单一元素的函数:applymap() 如何从上述函数中选择适合的函数,这取决于函数的操作对象。下面介绍了三种方法的使用。 操作整个数据表 通过给 pipe() 函数传递一个自定义函数和适当数量的参
由于健康检查失败,我无法进入GKE工作。我已经尝试了我能想到的所有调试步骤,包括: 已验证我没有任何配额不足 验证我的服务可以从集群内访问 验证我的服务在k8s/GKE负载均衡器后面工作。 验证检查正在传递Stackdrigs日志 ...我很乐意获得有关如何调试或修复的任何建议。详情如下! 我在GKE上设置了一个类型为的服务。通过外部IP效果很好: 然后,我尝试在同一服务上设置入口: 入口已创建,
在JavaScript中使用const可以设置什么类型的值,特别是函数,有没有限制?这有效吗?虽然它确实有效,但出于任何原因,它被认为是不好的做法吗? 在ES6中,所有函数都应该这样定义吗?如果是这样,这似乎并没有流行起来。