调用Constructor.newInstance()时为何无法直接使用Lambda表达式?
为什么Constructor.newInstance直接传Lambda编译失败,先赋值变量却可以?
核心差异在于编译器的类型推断逻辑
1. Constructor.newInstance的参数是Object类型,无法推断Lambda的目标类型
Constructor.newInstance()的方法签名是:
public T newInstance(Object... initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
它接收的是Object可变参数,Lambda表达式本身没有固定类型,必须依赖明确的「目标函数式接口类型」才能被编译。但Object不是函数式接口,编译器不知道该把这个Lambda转换成什么类型,所以会抛出"此表达式的目标类型必须是函数式接口"的错误。
2. 先赋值变量:提前明确了Lambda的目标类型
当你先声明DoubleSupplier supplier = () -> 3.0;时,变量类型已经明确是DoubleSupplier(标准函数式接口),编译器会自动把Lambda转换成该接口的实例。之后把这个实例作为Object传入newInstance,完全符合参数要求,自然编译通过。
3. 直接new实例:构造方法参数自带目标类型
new SubTypeA( () -> 3.0 )能成功,是因为SubTypeA的构造方法参数明确标注为DoubleSupplier,编译器可以直接把Lambda转换成该类型的实例,不需要额外推断,所以没问题。
快速解决:显式指定Lambda类型
如果不想单独声明变量,也可以通过强制类型转换告诉编译器Lambda的目标类型:
obj = ctor.newInstance( (DoubleSupplier) () -> 3.0 );
内容的提问来源于stack exchange,提问作者Jack Straub
相关产品推荐
相关产品推荐

