Skip to main content
 首页 » 编程设计

Java 无法在没有明显冗余类型转换的情况下正确推断流类型

2025年05月04日27虾米哥

我正在执行一系列流操作来展平有效的二维数组。

Arrays.stream(attributes) 
    .map(Attribute::getCommand) 
    .filter(Optional::isPresent) 
    .map(Optional::get) 
    .flatMap((array) -> (Arrays.stream((String[]) array))) 
    .toArray(String[]::new) 

哪里Attribute符合以下接口(interface):

public interface Attribute<T> { 
  Optional<String[]> getCommand();   
} 

然而,最终flatMap()调用未按预期运行。

  • .flatMap((array) -> (Arrays.stream((String[]) array)))工作得很好。

  • .flatMap((array) -> (Arrays.stream(array))) 编译失败 java: no suitable method found for stream(java.lang.Object) .

  • .flatMap(Arrays::stream) 编译失败 java: incompatible types: cannot infer type-variable(s) T (argument mismatch; java.lang.Object cannot be converted to T[]) .

在我看来,类型应该可以很好地推断出来。 IntelliJ 同意并将强制转换标记为冗余,并且三种实现中的任何一种都没有显示编译错误。 为什么 Java 需要这种明显多余的类型转换?


我还尝试了以下极简实现:

import java.util.Arrays; 
import java.util.Optional; 
 
public class Streaming { 
 
  public static void main(String[] args) { 
    Optional<String[]>[] myarray = new Optional[]{Optional.of(new String[]{"Hello", "world"}), 
        Optional.empty(), Optional.of(new String[]{"Foo"})}; 
    System.out.println(Arrays.toString(Arrays.stream(myarray).filter(Optional::isPresent).map 
        (Optional::get).flatMap(Arrays::stream).toArray(String[]::new))); 
  } 
 
} 

它在所有三种实现中都能正常工作,输出预期的 [Hello, world, Foo] .


编辑:

这被标记为 this question 的重复项。我可能是错的,但似乎存在区别,因为类型是以更明确的方式指定的。值得注意的是,IntelliJ 同意在上述帖子提供的示例中强制转换是必要的,但对于我的代码则不然。如果我错了,请告诉我。


编辑:

根据请求,声明attributesAttribute[] attributes = new Attribute[]{...}哪里...是Attribute的多种实现。

请您参考如下方法:

Attribute是一个泛型类(我想知道为什么不使用 T )。
如果出现此错误,则意味着您声明了原始类型,例如:

Attribute[] attributes = ...; 

对于原始类型,返回类型为 getCommand()声明为 Optional<String[]>变成 Optional .
声明Attribute作为泛型类型,例如:Attribute<String>[] attributes = ...;这应该在不进行强制转换的情况下进行编译,或者仅删除参数化类型 T如果不需要。