首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 8运行函数,无法确定int[]返回类型。

Java 8运行函数,无法确定int[]返回类型。
EN

Stack Overflow用户
提问于 2018-06-21 07:34:00
回答 1查看 206关注 0票数 4

假设我们有这样的lambda函数:

代码语言:javascript
复制
Function<ArrayList<Integer>, int[]> func1 = a->new int[2];

它所做的并不是很重要。重要的是:输入是ArrayList<Integer>,输出是int[]

使用一些基本测试可以编译和运行,而不会出现问题:

代码语言:javascript
复制
int[] func1Result1 = func1.apply(new ArrayList<Integer>()); // Non-currying works with <Integer>
System.out.println(func1Result1);
System.out.println(func1Result1.getClass());
System.out.println(Arrays.toString(func1Result1));
System.out.println();

int[] func1Result2 = func1.apply(new ArrayList<>());        // Non-currying works with <>
System.out.println(func1Result2);
System.out.println(func1Result2.getClass());
System.out.println(Arrays.toString(func1Result2));
System.out.println();

int[] func1Result3 = func1.apply(new ArrayList());          // Non-currying works without <>
System.out.println(func1Result3);
System.out.println(func1Result3.getClass());
System.out.println(Arrays.toString(func1Result3));
System.out.println();

在网上试试。

现在假设我们有一个像这样的运行lambda函数:

代码语言:javascript
复制
Function<Object, Function<Object, int[]>> func2 = a->b->new int[2];

再说一次,它所做的并不重要。这一次,当前函数接受两个Object参数,并且仍然输出一个int[]

使用相同的基本测试可以编译和运行,而不会再次出现问题:

代码语言:javascript
复制
int[] func2Result1 = func2.apply(new ArrayList<Integer>()).apply(null); // Currying works with <Integer>
System.out.println(func2Result1);
System.out.println(func2Result1.getClass());
System.out.println(Arrays.toString(func2Result1));
System.out.println();

int[] func2Result2 = func2.apply(new ArrayList<>()).apply(null);        // Currying works with <>
System.out.println(func2Result2);
System.out.println(func2Result2.getClass());
System.out.println(Arrays.toString(func2Result2));
System.out.println();

int[] func2Result3 = func2.apply(new ArrayList()).apply(null);          // Currying works without <>
System.out.println(func2Result3);
System.out.println(func2Result3.getClass());
System.out.println(Arrays.toString(func2Result3));
System.out.println();

在网上试试。

现在是第三个变体,我的困惑在哪里,我的问题在哪里。假设我们有这样一个运行lambda函数:

代码语言:javascript
复制
Function<ArrayList<Integer>, Function<Object, int[]>> func3 = a->b->new int[2];

这一次,参数是ArrayList<Integer>Object,返回类型仍然是int[]

这次使用相同的基本测试不会编译,并给出一个错误:

代码语言:javascript
复制
int[] func3Result1 = func3.apply(new ArrayList<Integer>()).apply(null); // Currying works with <Integer>
System.out.println(func3Result1);
System.out.println(func3Result1.getClass());
System.out.println(Arrays.toString(func3Result1));
System.out.println();

int[] func3Result2 = func3.apply(new ArrayList<>()).apply(null);        // Currying works with <>
System.out.println(func3Result2);
System.out.println(func3Result2.getClass());
System.out.println(Arrays.toString(func3Result2));
System.out.println();

int[] func3Result3 = func3.apply(new ArrayList()).apply(null);          // Currying doesn't work without <>
System.out.println(func3Result3);
System.out.println(func3Result3.getClass());
System.out.println(Arrays.toString(func3Result3));
System.out.println();

错误是:

Main.java:23:错误:不兼容类型:对象不能转换为int[] Int[] func3Result3 =Function3.Apply(新的ArrayList()).apply(null);// .apply没有<>就不能工作 /T1459.3-1993技术

在网上试试。

为什么它认为返回类型是Object而不是int[]?内部函数的返回类型清楚地表明返回类型是int[]。如果两个lambdas的参数都是Object ( func2测试),或者集合中附加了钻石(func3Result1func3Result2),那么它就可以正常工作。但是由于某种原因,当钻石从集合(func3Result3)中移除时,它会感到困惑,即使int[]返回类型与这个ArrayList<Integer>输入无关。

编辑:只是在我的jdk版本1.8.0_72上进行了本地测试,并在那里进行了编译和工作。有人能证实它确实不适用于JDK1.9或1.10 (或者JDK1.8的最新版本之一)吗?也许问题是TIO在这里做了一些奇怪的事情,而不是JDK本身。:S

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-21 08:41:28

总之。当您使用原始类型(如@Holger在注释中提到的你不应该用它们)时,您将删除任何泛型信息。所以这句话:

代码语言:javascript
复制
int[] func3Result3 = func3.apply(new ArrayList()).apply(null);

可分为多行以求澄清:

代码语言:javascript
复制
Function temp = func3.apply(new ArrayList());

在这里,只返回Function,因为使用原始类型new ArrayList()删除泛型信息。

而原始类型函数有点类似,但不等于Function<Object, Object>

这使得现在很容易看到,当将null应用于该函数时,您并不确切地知道返回的是什么(除了它是一个Object),这就是为什么要得到该错误:

代码语言:javascript
复制
int[] func3Result3 = temp.apply(null);

编译器只是不知道类型,因为类型擦除。

所以这件事的寓意是:

不要使用原始类型。它们只是一个向后兼容的特性,不应该在现代生产代码中使用。

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

https://stackoverflow.com/questions/50962862

复制
相关文章

相似问题

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