Java 类型推断未按预期工作

问题描述 投票:0回答:1

我似乎已经成功地打破了Java的类型推断,代码如下:

public static void main (String[] args)
{
    final VirtualFS vfs = new VirtualFS();
    vfs.addDirHandler(vf -> {
        // top level directory only,
        // return a list of all tags
        return Arrays.stream("@tag_one @tag_two @tag_three".split(" +"))
                .map(str -> (vf.getName() + str))
                .map(str -> new VirtualFile(str)) // <-- here
                .toList();
    });
    ...
}

以上工作正常,但如果我将标记行更改为:

                .map(VirtualFile::new) // <-- here

...然后它拒绝编译(尽管 IDE 不会抱怨它)。我还可以通过向之前的 .map 操作添加

(String)
转换来解决该问题。

.getName()
中的
VirtualFile
方法返回一个
String
。 Java版本是17,我的IDE是Intellij IDEA。就像我说的,我可以通过强制转换来解决问题,但我很好奇到底发生了什么混淆了类型推断。

我得到的编译器错误是:

java: incompatible types: invalid constructor reference
incompatible types: java.lang.Object cannot be converted to java.lang.String

最小可重现示例:

import java.util.function.Function;
import java.util.*;

public class VirtualFile
{
    private final String name;

    public VirtualFile(String name)
    {
        this.name = name;
    }

    public String getName () { return this.name; }

    private static class VirtualFS
    {
        public void addDirHandler (Function<VirtualFile, List<VirtualFile>> fn)
        {
        }
    }

    public static void main (String[] args)
    {
        final VirtualFS vfs = new VirtualFS();
        vfs.addDirHandler(vf -> {
            // top level directory only,
            // return a list of all tags
            return Arrays.stream("@tag_one @tag_two @tag_three".split(" +"))
                    .map(str -> vf.getName() + str)
                    .map(VirtualFile::new)
                    .toList();
        });
    }
}
java type-inference
1个回答
0
投票

这似乎是编译器错误 JDK-8268312,如果您在另一个采用

Function
(如
Stream.map
)的方法的 lambda 参数中调用采用
Function
(如 (
addDirHandler
))的方法,前一个调用的类型信息丢失。

这在 Java 20 中已修复。

© www.soinside.com 2019 - 2024. All rights reserved.